2017-06-22 144 views
1

我正在加密Erlang中的AES 256位CBC,然后使用c代码对其进行解密。而加密/解密在Erlang和C中工作,而不是从一个到另一个。Erlang中的AES-256/CBC加密和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: 

当我在二郎解密它工作正常,当我在密C也正常工作与同重点和四。 密码模式不匹配吗?虽然它看起来对我很正确。 任何指针都会非常有用。 谢谢

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

Erlang的二进制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>> 

这是通过二郎

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)中的文库FOF输出相同的数据发送。

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 

最后的16个字节从Erlang中丢失。是否有任何其他API需要从Erlang Crypto库调用?

+0

'数据'看起来像十六进制,但有一个逗号,有关逗号的任何提示?在十六进制加密输出将有所帮助。 – zaph

+0

您可以在将二进制数据发送给C之前发布它,以及当您收到C时是否正确? –

+0

逗号只是分开2个不同的键(内部使用) – user3404572

回答

3

你在看什么是差异填充。 OpenSSL总是使用PKCS#7定义的填充方案填充。在Erlang中,您使用密码对进行加密之前,使用零填充明文(这称为零填充)。密码本身不填(看起来)。由于明文是16的倍数(128位,即AES的块大小),因此OpenSSL例程将明文块添加一个完整的填充块 - 由16个字节组成的值为10的十六进制数组。

所以,如果你想匹配的密文,你应该使用EVP_CIPHER_CTX_set_padding(0)

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

+0

因为有明确的在Erlang中的应用程序级别填充在我看来,也会有应用程序级别的unpadding。填充已填充的明文是没有意义的。所以我走了这条路,而不是展示如何在Erlang中实现PKCS#7填充。 –

+0

感谢Maarten,通过上面的API了解你的意思,并首先尝试使用命令行加密-nopad并使用-nopad解密。有用。但是使用上面的API它不会。不知道-nopad是否正在调用其他API,但该文档说明了上面提到的内容。在传递上下文来解密API之前,我做了ctx = EVP_CIPHER_CTX_new();和EVP_CIPHER_CTX_set_padding(ctx,0); – user3404572

+0

你可以在调用init之后调用'set_padding'函数吗?我认为调用'init'会将其设置回PKCS#7。 –