openssl升级后,AES解密结果会有所不同

时间:2015-12-23 17:04:11

标签: c visual-c++ openssl aes

我链接到openssl 0.98的代码有一个AES解密功能,工作正常。

这是代码。

   const int bits = 256;
        AES_KEY key;
        iRes = AES_set_decrypt_key((const unsigned char *)szSecretKey, bits, &key);

        unsigned char szSigBytes[MAX_PATH] = "";
        unsigned char *pSigBytes = szSigBytes;
        unsigned char *pSignature = szSignature;
        AES_decrypt(pSignature, pSigBytes, &key);
        AES_decrypt(pSignature + 16, pSigBytes + 16, &key);

        cout<<pSigBytes<<endl;

但是,在迁移到openssl 1.0.1p之后,我不得不使用EVP函数,因为非EVP函数在FIPS模式下失败。所以我将代码修改为

EVP_CIPHER_CTX *ctx;    
            int len;


            int plaintext_len;
            int ciphertext_len = strlen((const char*)in);

            if(!(ctx = EVP_CIPHER_CTX_new()));


            if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, SecretKey, NULL))
            return;

          if(1 != EVP_DecryptUpdate(ctx, out, &len, in, ciphertext_len))
            return;

          if(1 != EVP_DecryptUpdate(ctx, out + 16, &len, in + 16, ciphertext_len - len))
            return; 

          EVP_DecryptFinal_ex(ctx, out + len, &len); 

          EVP_CIPHER_CTX_free(ctx);

结果几乎匹配,但对于少数最后一些字符。 任何想法,我在这里做错了什么?

编辑:我发现在使用EVP_DecryptUpdate时,第二个16字节没有被解密。

我已将第二个16字节提取到数组中并尝试解密它。我看到它在使用AES_decrypt时成功,但返回&#34;&#34;当我使用EVP_DecryptUpdate时。 密码长度仅为2个字节。这可能是解密失败的原因吗?

请参阅下面的修改后的代码。

    unsigned char temp[MAX_PATH] = "BoQ=\n";
    unsigned char result[MAX_PATH] = "";

    unsigned char data[MAX_PATH] = "";
    Decode(temp, data);


    //Decrypting with AES_Decrypt


   AES_KEY key;

unsigned char DecodedSecretKey[MAX_PATH];
ZeroMemory(DecodedSecretKey, MAX_PATH);
Decode(secretKey, DecodedSecretKey);


AES_set_decrypt_key((const unsigned char *)DecodedSecretKey, 256, &key);

AES_decrypt(data, result, &key);//result returns the proper result

/////////////////////////////////////////////// ////////////////////////////////////////////////// ///////////

//Decrypting with EVP_DecryptUpdate

EVP_CIPHER_CTX *ctx;    
        int len;


        int plaintext_len;
        int ciphertext_len = strlen((const char*)data);

        if(!(ctx = EVP_CIPHER_CTX_new()));


        if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, SecretKey, NULL))
        return;

      if(1 != EVP_DecryptUpdate(ctx, result, &len, data, ciphertext_len))
        return;


      EVP_DecryptFinal_ex(ctx, result + len, &len); 

      EVP_CIPHER_CTX_free(ctx);
//Here the array result is always empty

2 个答案:

答案 0 :(得分:1)

使用EVP_DecryptUpdate(ctx, out, &len, in, ciphertext_len)是错误的。

此处,len必须初始化为out数组中的字节数。据我所知,如果您使用len作为全长和cipthertext_len拨打一次,则必须解密所有加密文本。不需要第二次通话。之一:

len = <full length of buffer>;
EVP_DecryptUpdate(ctx, out, &len, in, ciphertext_len);

len = 16;
EVP_DecryptUpdate(ctx, out, &len, in, len);
len = 16;
EVP_DecryptUpdate(ctx, out+16, &len, in+16, len);

我更喜欢第一种方法。如果你需要特殊的填充,那么你可以使用额外的调用来处理最后一个块。

答案 1 :(得分:0)

我刚才发现了问题。这真是一个非常愚蠢的人。

int ciphertext_len = strlen((const char*)data);

我决定加密字符串的长度,使用strlen,这是错误的,我只是努力学习它。