在 C 中使用 openssl 解密时出现分段错误
Segmentation fault when decrypting with openssl in C
我正在尝试解密一条用 AES 192 ECB 加密的消息,但出现分段错误,我不知道该去哪里找了。我知道 ECB 不安全,但不适用于生产应用程序。
- 我已经检查了我的 readFile 方法,它有效(我写了密码
回到一个文件并用差异工具检查)
- 密钥长 24 字节(用 ls 和 hexdump 检查)
- 据我所知,ECB 没有 IV-Vector,所以我将其设置为 NULL
- 对于解密部分,我使用 https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption 中的示例开始
- 我认为问题出在 EVP_DecryptUpdate
- 我试图用 gdb 进一步追踪它,但我没有这方面的经验,只得到了
0x00007ffff798089d in ?? () from /usr/lib64/libcrypto.so.1.1
感谢您的宝贵时间。
#include <stdio.h>
#include <stdlib.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
#include <openssl/sha.h>
int readFile(char* filename, unsigned char** data){
FILE *fp;
unsigned char* tmp;
long fsize = 0;
if ((fp = fopen(filename, "rb")) == NULL){
perror(filename);
exit(EXIT_FAILURE);
}
// get length by going to end of the file and checking the position.
// Rewinding to start afterwards
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
rewind(fp);
if((tmp = malloc(fsize))){
fread(tmp, fsize, 1, fp);
fclose(fp);
} else {
fclose(fp);
perror(filename);
exit(EXIT_FAILURE);
}
*data = tmp;
return fsize;
}
int decryptAES192ECB(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, 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. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
*/
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_ecb(), NULL, key, NULL))
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;
}
int main(int argc, char **argv){
unsigned char *source_cipher, *source_key;
long source_cipher_len = readFile("source-cipher.bin", &source_cipher);
long source_key_len = readFile("source-key.bin", &source_key);
unsigned char* plaintext;
decryptAES192ECB(source_cipher, source_cipher_len, source_key, plaintext);
return 0;
}
编辑:解决方法是添加
unsigned char* plaintext = malloc(source_cipher_len);
解密 AES192ECB 调用之前的主要方法并删除
handleErrors();
在 EVP_DecryptFinal_ex 调用解密 AES192ECB 之后。
本文以热门评论开头。
your answer fixed it. The error on EVP_DecryptFinal_ex comes because of a wrong key Feel free to post your comment as an answer! – Akreter
plaintext
在 main
.
中 未初始化
我试过了:
unsigned char *plaintext = "abcdef";
这不太好用,我怀疑 plaintext
是一个 output 缓冲区,所以:
unsigned char *plaintext = malloc(1000000);
让您克服段错误。
但是,它会为 EVP_DecryptFinal_ex
生成错误 return,这是进度 [有点 ;-)]。
请注意,我只是将 [dummy] ascii 文本放入两个 .bin
文件中,因此了解这两个输入文件中应该包含哪些内容可能会有所帮助。有了 correct/real 数据,我认为事情会奏效 [正如你上面提到的]。
我正在尝试解密一条用 AES 192 ECB 加密的消息,但出现分段错误,我不知道该去哪里找了。我知道 ECB 不安全,但不适用于生产应用程序。
- 我已经检查了我的 readFile 方法,它有效(我写了密码 回到一个文件并用差异工具检查)
- 密钥长 24 字节(用 ls 和 hexdump 检查)
- 据我所知,ECB 没有 IV-Vector,所以我将其设置为 NULL
- 对于解密部分,我使用 https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption 中的示例开始
- 我认为问题出在 EVP_DecryptUpdate
- 我试图用 gdb 进一步追踪它,但我没有这方面的经验,只得到了
0x00007ffff798089d in ?? () from /usr/lib64/libcrypto.so.1.1
感谢您的宝贵时间。
#include <stdio.h>
#include <stdlib.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
#include <openssl/sha.h>
int readFile(char* filename, unsigned char** data){
FILE *fp;
unsigned char* tmp;
long fsize = 0;
if ((fp = fopen(filename, "rb")) == NULL){
perror(filename);
exit(EXIT_FAILURE);
}
// get length by going to end of the file and checking the position.
// Rewinding to start afterwards
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
rewind(fp);
if((tmp = malloc(fsize))){
fread(tmp, fsize, 1, fp);
fclose(fp);
} else {
fclose(fp);
perror(filename);
exit(EXIT_FAILURE);
}
*data = tmp;
return fsize;
}
int decryptAES192ECB(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, 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. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
*/
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_ecb(), NULL, key, NULL))
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;
}
int main(int argc, char **argv){
unsigned char *source_cipher, *source_key;
long source_cipher_len = readFile("source-cipher.bin", &source_cipher);
long source_key_len = readFile("source-key.bin", &source_key);
unsigned char* plaintext;
decryptAES192ECB(source_cipher, source_cipher_len, source_key, plaintext);
return 0;
}
编辑:解决方法是添加
unsigned char* plaintext = malloc(source_cipher_len);
解密 AES192ECB 调用之前的主要方法并删除
handleErrors();
在 EVP_DecryptFinal_ex 调用解密 AES192ECB 之后。
本文以热门评论开头。
your answer fixed it. The error on EVP_DecryptFinal_ex comes because of a wrong key Feel free to post your comment as an answer! – Akreter
plaintext
在 main
.
我试过了:
unsigned char *plaintext = "abcdef";
这不太好用,我怀疑 plaintext
是一个 output 缓冲区,所以:
unsigned char *plaintext = malloc(1000000);
让您克服段错误。
但是,它会为 EVP_DecryptFinal_ex
生成错误 return,这是进度 [有点 ;-)]。
请注意,我只是将 [dummy] ascii 文本放入两个 .bin
文件中,因此了解这两个输入文件中应该包含哪些内容可能会有所帮助。有了 correct/real 数据,我认为事情会奏效 [正如你上面提到的]。