使用 Openssl EVP 加密时出现分段错误:EVP_EncryptUpdate()
Segmentation Fault While Encrypting with Openssl EVP: EVP_EncryptUpdate()
我想使用 EVP 和 OpenSSL API 将我读入 unsigned char * 的 .exe 文件中的二进制数据加密。我对这个 API 不是很熟悉,恐怕我做错了什么会导致我在编译时遇到分段错误。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/aes.h>
void handleErrors(void){
ERR_print_errors_fp(stderr);
abort();
}
int main(){
//read in the exe file and convert its bytes to a string
FILE *inFile;
inFile = fopen("Quasar.exe","rb");
if (inFile == NULL){
perror("Failed to read in file\n");
}
printf("File read in complete!\n");
if(fseek(inFile , 0 , SEEK_END) == -1){
perror("Offset error\n");
};
unsigned long lSize = ftell(inFile);
if (lSize == -1){
perror("Size error\n");
}
rewind(inFile);
unsigned char *unencryptedText = (unsigned char*) malloc (sizeof(unsigned char)*lSize);
fread(unencryptedText,1,lSize,inFile);
fclose(inFile);
unsigned char *encryptedText = (unsigned char*) malloc (3 *(sizeof(unsigned char)*lSize));
//encrypt these bytes with open ssl
printf("Encrypting...\n");
int outlen, tmplen;
unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char iv[] = {1,2,3,4,5,6,7,8};
EVP_CIPHER_CTX *ctx = NULL;
EVP_CIPHER_CTX_init(ctx);
EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv);
if(!EVP_EncryptUpdate(ctx, encryptedText, &outlen, unencryptedText, lSize)){
return 0;
}
if(!EVP_EncryptFinal_ex(ctx, encryptedText + outlen, &tmplen)){
return 0;
}
outlen += tmplen;
EVP_CIPHER_CTX_cleanup(ctx);
return 0;
}
控制台输出如下:
File read in complete!
Encrypting...
zsh: segmentation fault ./binary
这是制作脚本:
all: crypter.c
gcc -Wall -g -I/usr/local/include/openssl -L/usr/lib -lssl -lcrypto crypter.c -o binary
clean:
rm -f crypter
EVP_CIPHER_CTX *ctx = NULL;
EVP_CIPHER_CTX_init(ctx);
EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv);
除了 NULL
之外,您绝不会为 ctx
分配任何值。您将 NULL
传递给上述两个函数。
您可能想要的是:
ECP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
请注意这不会将 NULL
传递给 EVP_CIPHER_CTX_init
?
您正在将 NULL 对象传递给 EVP_CIPHER_CTX_init
此函数需要现有 EVP_CIPHER_CTX
对象的地址。
您可以通过创建 EVP_CIPHER_CTX
的实例并将其地址传递给需要它的每个函数来解决此问题,或者如果您想尽量减少对代码的更改,您可以将此对象的地址分配给现有 ctx
个指针。
EVP_CIPHER_CTX ctx_obj;
EVP_CIPHER_CTX *ctx = &ctx_obj;
编辑:
根据评论,您似乎使用的是 OpenSSL 1.1 或更高版本。在这种情况下,您想改用 EVP_CIPHER_CTX_new
来实例化一个新的上下文:
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
我想使用 EVP 和 OpenSSL API 将我读入 unsigned char * 的 .exe 文件中的二进制数据加密。我对这个 API 不是很熟悉,恐怕我做错了什么会导致我在编译时遇到分段错误。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/aes.h>
void handleErrors(void){
ERR_print_errors_fp(stderr);
abort();
}
int main(){
//read in the exe file and convert its bytes to a string
FILE *inFile;
inFile = fopen("Quasar.exe","rb");
if (inFile == NULL){
perror("Failed to read in file\n");
}
printf("File read in complete!\n");
if(fseek(inFile , 0 , SEEK_END) == -1){
perror("Offset error\n");
};
unsigned long lSize = ftell(inFile);
if (lSize == -1){
perror("Size error\n");
}
rewind(inFile);
unsigned char *unencryptedText = (unsigned char*) malloc (sizeof(unsigned char)*lSize);
fread(unencryptedText,1,lSize,inFile);
fclose(inFile);
unsigned char *encryptedText = (unsigned char*) malloc (3 *(sizeof(unsigned char)*lSize));
//encrypt these bytes with open ssl
printf("Encrypting...\n");
int outlen, tmplen;
unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char iv[] = {1,2,3,4,5,6,7,8};
EVP_CIPHER_CTX *ctx = NULL;
EVP_CIPHER_CTX_init(ctx);
EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv);
if(!EVP_EncryptUpdate(ctx, encryptedText, &outlen, unencryptedText, lSize)){
return 0;
}
if(!EVP_EncryptFinal_ex(ctx, encryptedText + outlen, &tmplen)){
return 0;
}
outlen += tmplen;
EVP_CIPHER_CTX_cleanup(ctx);
return 0;
}
控制台输出如下:
File read in complete!
Encrypting...
zsh: segmentation fault ./binary
这是制作脚本:
all: crypter.c
gcc -Wall -g -I/usr/local/include/openssl -L/usr/lib -lssl -lcrypto crypter.c -o binary
clean:
rm -f crypter
EVP_CIPHER_CTX *ctx = NULL;
EVP_CIPHER_CTX_init(ctx);
EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv);
除了 NULL
之外,您绝不会为 ctx
分配任何值。您将 NULL
传递给上述两个函数。
您可能想要的是:
ECP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
请注意这不会将 NULL
传递给 EVP_CIPHER_CTX_init
?
您正在将 NULL 对象传递给 EVP_CIPHER_CTX_init
此函数需要现有 EVP_CIPHER_CTX
对象的地址。
您可以通过创建 EVP_CIPHER_CTX
的实例并将其地址传递给需要它的每个函数来解决此问题,或者如果您想尽量减少对代码的更改,您可以将此对象的地址分配给现有 ctx
个指针。
EVP_CIPHER_CTX ctx_obj;
EVP_CIPHER_CTX *ctx = &ctx_obj;
编辑:
根据评论,您似乎使用的是 OpenSSL 1.1 或更高版本。在这种情况下,您想改用 EVP_CIPHER_CTX_new
来实例化一个新的上下文:
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();