C EVP加密核心转储
我正在尝试解密使用C EVP加密核心转储,c,encryption,openssl,C,Encryption,Openssl,我正在尝试解密使用EVP中的AES\u 128\u cbc()加密的密码文本,密码文本存在于名为task3.bin的文件中。我正在尝试进行模拟解密试验,这意味着解密不是使用正确的密钥或iv,而是使用有效长度 这两个函数是从EVP复制和粘贴的,但作为解密方法,EVP_aes_256_cbc()已更改为EVP_aes_128_cbc() void handleErrors(void) { ERR_print_errors_fp(stderr); abort(); } int decrypt
EVP
中的AES\u 128\u cbc()
加密的密码文本,密码文本存在于名为task3.bin
的文件中。我正在尝试进行模拟解密试验,这意味着解密不是使用正确的密钥
或iv
,而是使用有效长度
这两个函数是从EVP复制和粘贴的,但作为解密方法,EVP_aes_256_cbc()
已更改为EVP_aes_128_cbc()
void handleErrors(void) {
ERR_print_errors_fp(stderr);
abort();
}
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. (changed 256 to 128 HERE!!!)*/
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_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;
}
这是我的main
函数,它正在调用decrypt
int main(void) {
FILE *f;
long lSize;
char *buffer;
char *ciphertext;
unsigned char *iv;
unsigned char *key;
unsigned char decryptedtext[128];
int decryptedtext_len;
// read ciphertext
f = fopen("task3.bin", "rb");
fseek( f , 0L , SEEK_END);
lSize = ftell( f );
rewind( f );
ciphertext = calloc( 1, lSize+1 );
fread(ciphertext , lSize, 1 , f);
fclose(f);
// testing key and iv
key = (unsigned char *)"0123456789012345";
iv = (unsigned char *)"0000000000000000";
// decrypt!
decryptedtext_len = decrypt(ciphertext, strlen((char *)ciphertext), key, iv, decryptedtext);
return 0;
}
我得到了错误139864800151232:error:06065064:lib(6):func(101):reason(100):evp_enc.c:529:
中止(内核转储)
,我花了数小时查看它,但没有取得多大成功。任何精通OpenSSL的人,请提供帮助
错误来自
EVP\u decrypt final\u ex
,最后一次EVP
调用decrypt
。我只能假设某些长度分配不正确。如果您解密使用PKCS加密的数据#7填充(通常情况下),使用不正确的密钥解密将在大多数情况下导致填充错误
由于填充在最后一个块中,因此在EVP\u DecryptFinal
调用中会对其进行检查,以便所有内容都有意义
根据加密算法、模式和填充量等因素,模拟解密很难实现
注意:OpenSSL EVP文档声明:“OpenSSL默认使用PKCS填充”,这是一个借口,因为它不声明PKCS#5或PKCS#7。我必须假设PKCS#7适用于AES。任何地方都没有错误检查-您是否至少使用了调试器(或printf)来查看它在崩溃之前能走多远?是的。我已经更新了我的问题@john3136在
EVP\u decryptofinal
调用中检查填充,请参阅更新的答案。AES或其他现代算法的密文本质上是随机字节值,可以包括0 aka NUL,因此,使用strlen
通常会给出错误的长度,即使后面有一个0,正如您通过calloc
-ing(从而归零)一个额外的字节所保证的那样。在您的示例中,使用读取的长度lSize
。EVP\u Encrypt/Decrypt/Cipher*
和EVP\u Cipher\u CTX.*
手册页的注释部分说,“PKCS填充通过添加n个值为n的填充字节来工作,以使加密数据的总长度为块大小的倍数。填充总是添加[偶数]如果数据已经是块大小的倍数……”这无疑是PKCS7,即使它没有使用该标签(我同意它应该使用)。