zoukankan      html  css  js  c++  java
  • 关于OPENSSL的EVP函数的使用

    4月份没什么做,就是做了OPENSSL的 加密和解密的应用,现在公开一下如何调用OPENSSL对字符串进行加密和解密,当中也学会了对加密数据进行BASE64编码,现在公开一下代码,在这感谢GITHUB里的好心人

    //加密例子

    int encryptdate(string plaindatas, string & encryptedatas)
    {



    const unsigned char iv[8] = { '1', '2', '3', '4, '5', '6', '7', '8' };

    const unsigned char key[8] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };

    const unsigned char * in = reinterpret_cast<const unsigned char *> (plaindatas.c_str());

    int written = 0, temp;
    unsigned char * outbuf = new unsigned char[plaindatas.length()+1];
    int in_len = plaindatas.length();

    EVP_CIPHER_CTX *ctx;
    if (!(ctx = EVP_CIPHER_CTX_new()))
    {
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_CIPHER_CTX_new failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    return -1;
    }

    if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_cbc(), NULL, key, iv))
    {
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_EncryptInit_ex failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }


    EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);

    if (1 != EVP_EncryptUpdate(ctx, outbuf, &temp, in, in_len))
    {
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_EncryptUpdate failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }

    written = temp;

    if (1 != EVP_EncryptFinal_ex(ctx, outbuf + temp, &temp))
    {
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_EncryptFinal_ex failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }

    written += temp;

    //EVP_CIPHER_CTX_free(ctx);
    EVP_CIPHER_CTX_cleanup(ctx);

    encryptedatas = base64_encode(outbuf, written);
    return 0;
    }

    //解密


    int decryptdate(string encryptdatas, string & decryptdatas)
    {


    const unsigned char iv[8] =  { '1', '2', '3', '4, '5', '6', '7', '8' };

    const unsigned char key[8] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };

    string decordstr = my_base64_decode(encryptdatas);

    EVP_CIPHER_CTX * ctx;

    int len=0;

    int plaintext_len=0;

    int ciphertext_len = decordstr.length();
    unsigned char * ciphertext = new unsigned char[ciphertext_len]; //这个size 要大于 str.size();
    memcpy(ciphertext, &decordstr[0], decordstr.size());

    unsigned char * plaintext = new unsigned char[ciphertext_len];


    /* Create and initialise the context */
    if (!(ctx = EVP_CIPHER_CTX_new())) {
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_CIPHER_CTX_new failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);

    // EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }

    /* Initialise the decryption operation. IMPORTANT - ensure you use a key
    * and IV size appropriate for your cipher
    * In this example we are using 256 bit AES (i.e. a 256 bit key). The
    * IV size for *most* modes is the same as the block size. For AES this
    * is 128 bits */
    if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_cbc(), NULL, key, iv)){
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_DecryptInit_ex failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }
    /* Provide the message to be decrypted, and obtain the plaintext output.
    * EVP_DecryptUpdate can be called multiple times if necessary
    */
    if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)){
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_DecryptUpdate failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }
    plaintext_len = len;

    /* Finalise the decryption. Further plaintext bytes may be written at
    * this stage.
    */
    if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)){
    string errstr = ERR_error_string(ERR_get_error(), NULL);
    errstr = "ERROR: EVP_DecryptFinal_ex failed. OpenSSL error:" + errstr;
    write_text_to_log_file(errstr);
    EVP_CIPHER_CTX_cleanup(ctx);
    return -1;
    }

    plaintext_len += len;

    plaintext[plaintext_len] = 0;

    decryptdatas = (reinterpret_cast<char const *>(plaintext));

    /* Clean up */
    EVP_CIPHER_CTX_cleanup(ctx);


    return 0;
    }

     而base64的代码如下,我测试过可行

    //编码

    #include <iostream>

    static const std::string base64_chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/";


    static inline bool is_base64(unsigned char c) {
    return (isalnum(c) || (c == '+') || (c == '/'));
    }

    std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
    std::string ret;
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];

    while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (i = 0; (i <4); i++)
    ret += base64_chars[char_array_4[i]];
    i = 0;
    }
    }

    if (i)
    {
    for (j = i; j < 3; j++)
    char_array_3[j] = '';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

    for (j = 0; (j < i + 1); j++)
    ret += base64_chars[char_array_4[j]];

    while ((i++ < 3))
    ret += '=';

    }

    return ret;

    }

    //base64解码

    #include <cassert>
    #include <limits>
    #include <stdexcept>
    #include <cctype>

    static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    static const char reverse_table[128] = {
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
    64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64
    };

    ::std::string my_base64_decode(const ::std::string &ascdata)
    {
    using ::std::string;
    string retval;
    const string::const_iterator last = ascdata.end();
    int bits_collected = 0;
    unsigned int accumulator = 0;

    for (string::const_iterator i = ascdata.begin(); i != last; ++i) {
    const int c = *i;
    if (::std::isspace(c) || c == '=') {
    // Skip whitespace and padding. Be liberal in what you accept.
    continue;
    }
    if ((c > 127) || (c < 0) || (reverse_table[c] > 63)) {
    throw ::std::invalid_argument("This contains characters not legal in a base64 encoded string.");
    }
    accumulator = (accumulator << 6) | reverse_table[c];
    bits_collected += 6;
    if (bits_collected >= 8) {
    bits_collected -= 8;
    retval += static_cast<char>((accumulator >> bits_collected) & 0xffu);
    }
    }
    return retval;
    }

  • 相关阅读:
    表单元素(控件)不可见属性“visibility”和“display”分析
    如何实现网页的右键菜单功能
    Google Chrome 11 浏览器 下Flash Debug 插件无效的解决办法
    embed区别object
    在Fedora 12 下安装Intel X4500 显卡驱动
    HDOJ 2000
    费马小定理
    HDOJ 2055
    HDOJ 1018(阶乘位数)
    大数阶乘所得数位数的定理
  • 原文地址:https://www.cnblogs.com/redmondfan/p/10944078.html
Copyright © 2011-2022 走看看