Erlang&中的AES-256 / CBC加密C中的解密不起作用

时间:2017-06-22 20:51:47

标签: c encryption openssl erlang aes

我在Erlang中加密AES 256位CBC然后在c代码中解密它时遇到问题。加密/解密在Erlang和C中工作,但不能在一个到另一个工作。

Ivec = "1200000000000000",
Key = "586E36EEE726B37F70A6F7B770764E99",
Data = "encrypt[38ce517c95b011bbfc999f36d09e4feb92d22dd8,38ce517c95b011bbfc999f36d09e4feb92d22222]",
PaddedText = string:left(Data ++ ",",128,$0),
%%Data is "encrypt[38ce517c95b011bbfc999f36d09e4feb92d22dd8,38ce517c95b011bbfc999f36d09e4feb92d22222],0000000000000000000000000000000000000"
EncryptedText = crypto:block_encrypt(aes_cbc256, Key, Ivec, PaddedText),
%%Send to C code

和c代码

unsigned char *key = (unsigned char *)"586E36EEE726B37F70A6F7B770764E99";
unsigned char *iv = (unsigned char *)"1200000000000000";

EVP_CIPHER_CTX *ctx;
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)
EVP_DecryptUpdate(ctx, plaintext, &len, buf, buf_len)

我得到的错误是

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:

当我在Erlang中解密时,它工作正常,当我在C中加密时,它也适用于相同的Key和IV。 它是否是密码模式不匹配。虽然看起来对我来说是正确的。 任何指针都非常有用。 感谢

我弄清楚,我在C中加密和解密的相同数据然后进行了十六进制转储。实际的加密数据Erlang是senginh是128字节,C openssl库加密的相同数据是144字节。这是正常的密文通常很长。这是输出。

Erlang Binary在Enryption之后回归:

<<165,171,208,104,24,97,173,130,177,99,50,22,51,180,112,123,36,18,208,170,250,131,195,162,182,162,253,14,121,242,61,60,202,172,74,121,223,50,128,255,134,51,253,91,195,174,90,93,77,65,1,115,119,64,25,131,47,245,68,156,163,145,111,125,143,208,255,53,131,220,174,243,64,120,229,21,86,107,139,148,164,39,144,106,232,64,252,234,26,208,138,187,213,244,210,11,174,47,126,4,97,179,194,85,8,207,116,140,236,3,145,209,95,106,36,121,241,228,153,120,226,125,227,138,130,183,217,39>>

这是由Erlang发送的

    Encrypted =  128

a5 ab d0 68 18 61 ad 82 b1 63 32 16 33 b4 70 7b  
24 12 d0 aa fa 83 c3 a2 b6 a2 fd 0e 79 f2 3d 3c 
ca ac 4a 79 df 32 80 ff 86 33 fd 5b c3 ae 5a 5d 
4d 41 01 73 77 40 19 83 2f f5 44 9c a3 91 6f 7d 
8f d0 ff 35 83 dc ae f3 40 78 e5 15 56 6b 8b 94 
a4 27 90 6a e8 40 fc ea 1a d0 8a bb d5 f4 d2 0b 
ae 2f 7e 04 61 b3 c2 55 08 cf 74 8c ec 03 91 d1
5f 6a 24 79 f1 e4 99 78 e2 7d e3 8a 82 b7 d9 27 

这是输出Openssl(c)库的相同数据。

Encrypted = 144

a5 ab d0 68 18 61 ad 82 b1 63 32 16 33 b4 70 7b  
24 12 d0 aa fa 83 c3 a2 b6 a2 fd 0e 79 f2 3d 3c  
ca ac 4a 79 df 32 80 ff 86 33 fd 5b c3 ae 5a 5d 
4d 41 01 73 77 40 19 83 2f f5 44 9c a3 91 6f 7d 
8f d0 ff 35 83 dc ae f3 40 78 e5 15 56 6b 8b 94 
a4 27 90 6a e8 40 fc ea 1a d0 8a bb d5 f4 d2 0b  
ae 2f 7e 04 61 b3 c2 55 08 cf 74 8c ec 03 91 d1 
5f 6a 24 79 f1 e4 99 78 e2 7d e3 8a 82 b7 d9 27 
f7 01 c0 ed 95 e3 14 e5 d2 62 21 da a9 1d 2a e7  

Erlang缺少最后16个字节。我需要从Erlang Crypto库调用其他API吗?

1 个答案:

答案 0 :(得分:3)

您所看到的是填充的区别。 OpenSSL总是使用PKCS#7定义的填充方案填充。在Erlang中,在使用密码加密之前,使用零(<称为零填充)填充明文。密码本身不会填充(似乎)。

由于明文是16的倍数(128位,AES的块大小),一个完整的填充块 - 由十六进制的16个字节值10组成 - 由OpenSSL例程添加到明文中。

因此,如果您想匹配密文,请使用EVP_CIPHER_CTX_set_padding(0)

  

EVP_CIPHER_CTX_set_padding()启用或禁用填充。默认情况下,使用标准块填充填充加密操作,并在解密时检查和删除填充。如果pad参数为零,则不执行填充,则加密或解密的数据总量必须是块大小的倍数,否则将发生错误。