sch*_*r22 6 c++ encryption dll openssl aes
我正在尝试使用c ++ openssl和aes cbc加密和解密字符串.
关于这一点的奇怪之处在于,它可以在一台PC上运行,而在另一台PC上却没有.我只有3/4的原始字符串,所以结尾是错误的.
另一个奇怪的是,当我在第二台PC上的exe文件目录中添加一个名为"libeay32.dll"的DLL时,它可以工作,但不能在第一台PC上运行.
总之,第一台PC只能在没有dll的情况下工作,第二台PC只能用于dll.
我的问题是,这段代码可以改进吗,为什么在一台计算机上需要这个dll而在另一台计算机上不需要.
这是我已经写的:
KEY和Iv定义如下:
#define KEY "abc"
#define Iv "abc"
Run Code Online (Sandbox Code Playgroud)
加密功能:
string aes_encrypt(string _InStr)
{
string EncKey,
EncIV;
AES_KEY enc_key;
unsigned char * aes_key = (unsigned char *) malloc (sizeof(unsigned char) * (32)),
* iv_enc = (unsigned char *) malloc (sizeof(unsigned char) * AES_BLOCK_SIZE),
* aes_input = (unsigned char *) malloc (sizeof(unsigned char) * _InStr.size ()),
* enc_out = (unsigned char *) malloc (sizeof(unsigned char) * ((_InStr.size () + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
memcpy ((char *) aes_input, _InStr.c_str (), _InStr.size ());
memset (aes_key, 0, 32);
EncKey = KEY;
EncIV = Iv;
for (int i = 0; i < 50; i++)
EncKey = md5 (EncKey.c_str ());
for (int i = 0; i < 305; i++)
EncIV = md5 (EncIV.c_str ());
EncIV.erase (16);
memcpy (aes_key, EncKey.c_str (), 32);
memcpy (iv_enc, EncIV.c_str (), 16);
AES_set_encrypt_key (aes_key, 128, &enc_key);
AES_cbc_encrypt (aes_input, enc_out, _InStr.size (), &enc_key, iv_enc, AES_ENCRYPT);
free (aes_key);
free (aes_input);
free (iv_enc);
aes_key = NULL;
aes_input = NULL;
iv_enc = NULL;
return string ((char *) enc_out);
}
Run Code Online (Sandbox Code Playgroud)
解密功能:
string aes_decrypt (string _InStr)
{
string EncKey,
EncIV;
AES_KEY dec_key;
unsigned char * aes_key = (unsigned char *) malloc (sizeof(unsigned char) * (32)),
* iv_dec = (unsigned char *) malloc (sizeof(unsigned char) * AES_BLOCK_SIZE),
* enc_out = (unsigned char *) malloc (sizeof(unsigned char) * _InStr.size ()),
* dec_out = (unsigned char *) malloc (sizeof(unsigned char) * _InStr.size ());
memcpy (enc_out, _InStr.c_str (), _InStr.size ());
memset (aes_key, 0, 32);
EncKey = KEY;
EncIV = Iv;
for (int i = 0; i < 50; i++)
EncKey = md5 (EncKey.c_str ());
for (int i = 0; i < 305; i++)
EncIV = md5 (EncIV.c_str ());
EncIV.erase (16);
memcpy (aes_key, EncKey.c_str (), 32);
memcpy (iv_dec, EncIV.c_str (), 16);
AES_set_decrypt_key(aes_key, 128, &dec_key);
AES_cbc_encrypt(enc_out, dec_out, _InStr.size (), &dec_key, iv_dec, AES_DECRYPT);
free (aes_key);
free (iv_dec);
free (enc_out);
aes_key = NULL;
iv_dec = NULL;
enc_out = NULL;
return string ((char *) dec_out);
}
Run Code Online (Sandbox Code Playgroud)
第一台PC的输出:
输入:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
加密:
小号^Wo◄┘"â▼〜¼\é╣$╨L╡`aC♠·ñZ½h╠∟≥ä°╪╥=αp╙IφoCYN°☺§)↨XwY+☼▀╤M▓÷√NÉk┼≡< ák◄Ä┬÷∙z¼üt@¥≈╟∙√Ñù°7å²²²²½½½½½½½½■ε■
解密:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
第二台PC的输出:
输入:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
加密:
小号^ WO 3 +"一个?〜¼\ $英哩ðLÁ`aC?·ñZ½h|?= A°IE =ÓpËIÝoCYN°?§)?XWY +¤¯ÐM|÷¹NÉk+ <AK?A-÷ZD +BñFb宇]?的
解密:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa无线»H +²²²²||||||w$○○?:
这两个肯定是坏掉了……
for (int i = 0; i < 50; i++)
EncKey = md5 (EncKey.c_str ());
for (int i = 0; i < 305; i++)
EncIV = md5 (EncIV.c_str ());
Run Code Online (Sandbox Code Playgroud)
你需要类似的东西:
EncKey = string(md5 (EncKey.c_str ()), 16);
Run Code Online (Sandbox Code Playgroud)
否则,MD5 生成的字符串将在string构造函数遇到的第一个 0x00 处被截断。
这些都是麻烦:
memcpy (aes_key, EncKey.c_str (), 32);
memcpy (iv_enc, EncIV.c_str (), 16);
Run Code Online (Sandbox Code Playgroud)
最多MD5生成一个 16 字节的字符串。您无法从 . 中的 16 字节字符串中提取 32 字节EncKey。
EncKey如果或EncIV嵌入了空值,您就会遇到麻烦。如果其中一个有,那么该字符串甚至不是 16 个字节。
正如吉姆在下面的评论中指出的那样,这也是一个麻烦:
return string ((char *) dec_out);
Run Code Online (Sandbox Code Playgroud)
它需要类似于:
string aes_encrypt(string _InStr)
{
...
return string ((char *) dec_out, <some size>);
}
Run Code Online (Sandbox Code Playgroud)
而且你的使用AES_cbc_encrypt看起来是错误的。您应该坚持使用EVP_*界面。有关示例,请参阅OpenSSL wiki 上的EVP 对称加密和解密。
更好的是,使用 GCM 等经过身份验证的加密模式,这样您也可以获得真实性/完整性保证。有关示例,请参阅OpenSSL wiki 上的EVP 验证加密和解密。
最后,使用更大的散列,例如SHA256或SHA512。除了向后兼容性之外,MD5 不再需要任何其他用途。
| 归档时间: |
|
| 查看次数: |
8201 次 |
| 最近记录: |