OpenSSL 1.1.0 C ++ 34800:错误:0606506D:数字信封例程:EVP_DecryptFinal_ex:错误的最终块长度:crypto \ evp \ evp_enc.c:525:

时间:2018-09-16 19:29:40

标签: c

加密/解密方法

https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
    unsigned char *iv, unsigned char *ciphertext)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;

    /* Create and initialise the context */
    if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    /* Initialise the encryption 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_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
        handleErrors();

    /* Provide the message to be encrypted, and obtain the encrypted output.
    * EVP_EncryptUpdate can be called multiple times if necessary
    */
    if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        handleErrors();
    ciphertext_len = len;

    /* Finalise the encryption. Further ciphertext bytes may be written at
    * this stage.
    */
    if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
    ciphertext_len += len;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
    unsigned char *iv, unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int plaintext_len;

    /* Create and initialise the context */
    if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

    /* 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_256_cbc(), NULL, key, iv))
        handleErrors();

    /* 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))
        handleErrors();
    plaintext_len = len;

    /* Finalise the decryption. Further plaintext bytes may be written at
    * this stage.
    */
    if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
    plaintext_len += len;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return plaintext_len;
}

由于要使用BSTR类型,因此计划在ATL DLL中使用。

方法:

BSTR ENCRYPT(BSTR in, BSTR key) {
    unsigned char * pBuffer = bstr_char(in);

    unsigned char * key_v = bstr_char(key);

    unsigned char *key_ = (unsigned char*)"857759686370038057";

    char *temp = (char *)malloc(strlen((char*)key_v) + strlen((char*)key_) + 1);
    strcpy(temp, (char*)key_);
    strcat(temp, (char*)key_v);

    unsigned char *iv = (unsigned char*)"2371904392800624";//(unsigned char*)"199618872547325";

    unsigned char ciphertext[5000];

    int ciphertext_len;

    ciphertext_len = encrypt(pBuffer, strlen((char *)pBuffer), (unsigned char*)temp, iv, ciphertext);

    ciphertext[ciphertext_len] = '\0';

    std::string encoded = base64_encode(ciphertext, strlen((char *)ciphertext));

    ULONG ulSize = strlen((char*)reinterpret_cast<const unsigned char*>(encoded.c_str())) + sizeof(char);
    char* pszReturn = NULL;

    pszReturn = (char*)::CoTaskMemAlloc(ulSize);
    strcpy(pszReturn, (char*)(char*)reinterpret_cast<const unsigned char*>(encoded.c_str()));
    BSTR out = SysAllocString(CA2W(pszReturn));

    pBuffer = NULL;
    key_v = NULL;
    key_ = NULL;
    temp = NULL;
    iv = NULL;
    return out;
}

BSTR DECRYPT(BSTR in, BSTR key) {
    unsigned char * pBuffer = bstr_char(in);

    unsigned char * key_v = bstr_char(key);

    unsigned char *key_ = (unsigned char*)"857759686370038057";

    char *temp = (char *)malloc(strlen((char*)key_v) + strlen((char*)key_) + 1);
    strcpy(temp, (char*)key_);
    strcat(temp, (char*)key_v);

    unsigned char *iv = (unsigned char*)"2371904392800624";// (unsigned char*)"199618872547325";;
    unsigned char decryptedtext[5000];

    int decryptedtext_len;

    std::string sName(reinterpret_cast<char*>(pBuffer));
    std::string decoded = base64_decode(sName);

    /* _DECRYPT_AES_ the ciphertext */
    decryptedtext_len = decrypt((unsigned char*)reinterpret_cast<const unsigned char*>(decoded.c_str()),
        strlen((char *)(char*)reinterpret_cast<const unsigned char*>(decoded.c_str())), (unsigned char*)temp, iv,
        decryptedtext);

    /* Add a NULL terminator. We are expecting printable text */
    decryptedtext[decryptedtext_len] = '\0';

    ULONG ulSize = strlen((char*)decryptedtext) + sizeof(char);
    char* pszReturn = NULL;

    pszReturn = (char*)::CoTaskMemAlloc(ulSize);

    strcpy(pszReturn, (char*)decryptedtext);

    BSTR out = SysAllocString(CA2W(pszReturn));

    pBuffer = NULL;
    key_v = NULL;
    key_ = NULL;
    temp = NULL;
    iv = NULL;
    return out;
}

Преобразованиетипов

unsigned char* bstr_char(BSTR in) {
    int bstrLen = SysStringLen(in) + 1;
    int len = WideCharToMultiByte(CP_ACP, 0, in, bstrLen, NULL, 0,
        NULL, NULL);
    unsigned char * pBuffer = new unsigned char[len];
    WideCharToMultiByte(CP_ACP, 0, in, bstrLen, LPSTR(pBuffer), len,
        NULL, NULL);
    return pBuffer;
}

主要:

void main()
{
    for (int i = 0; i < 100; i++) {
        BSTR KEY = GET_PARAM_();
        BSTR ENCR = ENCRYPT(SysAllocString(L"new string"), KEY);
        BSTR decr = DECRYPT(ENCR, KEY);
        wcout << ENCR << endl;
        wcout << decr << endl;
        cout << "----------------------------------" << endl;
    }
    system("pause");
}

After 10 or 12 run program error: 2628:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:crypto\evp\evp_enc.c:525:

0 个答案:

没有答案