c++ - 通过Openssl命令行加密,通过c++解密
问题描述
我正在尝试通过 openssl 命令行加密文件并通过 C++ 解密它们。我正在运行命令:
openssl enc -aes-256-cbc -e -in test.txt -out test.txt.enc -K (64 character length key) -iv (32 character length iv)
和继承我的 C++ 代码解密:
typedef struct cipher_params_t {
unsigned char *key;
unsigned char *iv;
unsigned int encrypt;
const EVP_CIPHER *cipher_type;
}
void file_decrypt(cipher_params_t *params, FILE *ifp, FILE *ofp){
int cipher_block_size = EVP_CIPHER_block_size(params->cipher_type);
unsigned char in_buf[BUFSIZE], out_buf[BUFSIZE + cipher_block_size];
int num_bytes_read, out_len;
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
if(ctx == NULL){
fprintf(stderr, "ERROR: EVP_CIPHER_CTX_new failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
cleanup(params, ifp, ofp, ERR_EVP_CTX_NEW);
}
if(!EVP_DecryptInit_ex(ctx, params-> cipher_type, NULL, params->key, params->iv)){
fprintf(stderr, "ERROR: EVP_CipherInit_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_cleanup(ctx);
cleanup(params, ifp, ofp, ERR_EVP_CIPHER_INIT);
}
while(1){
num_bytes_read = fread(in_buf, sizeof(unsigned char), BUFSIZE, ifp);
if (ferror(ifp)){
fprintf(stderr, "ERROR: fread error: %s\n", strerror(errno));
EVP_CIPHER_CTX_cleanup(ctx);
cleanup(params, ifp, ofp, errno);
}
if(!EVP_DecryptUpdate(ctx, out_buf, &out_len, in_buf, num_bytes_read)){
fprintf(stderr, "ERROR: EVP_CipherUpdate failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_cleanup(ctx);
cleanup(params, ifp, ofp, ERR_EVP_CIPHER_UPDATE);
}
fwrite(out_buf, sizeof(unsigned char), out_len, ofp);
if (ferror(ofp)) {
fprintf(stderr, "ERROR: fwrite error: %s\n", strerror(errno));
EVP_CIPHER_CTX_cleanup(ctx);
cleanup(params, ifp, ofp, errno);
}
if (num_bytes_read < BUFSIZE) {
/* Reached End of file */
break;
}
}
/* Now cipher the final block and write it out to file */
if(!EVP_DecryptFinal_ex(ctx, out_buf, &out_len)){
fprintf(stderr, "ERROR: EVP_CipherFinal_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_cleanup(ctx);
cleanup(params, ifp, ofp, ERR_EVP_CIPHER_FINAL);
}
fwrite(out_buf, sizeof(unsigned char), out_len, ofp);
if (ferror(ofp)) {
fprintf(stderr, "ERROR: fwrite error: %s\n", strerror(errno));
EVP_CIPHER_CTX_cleanup(ctx);
cleanup(params, ifp, ofp, errno);
}
EVP_CIPHER_CTX_cleanup(ctx);
}
int main()
{
FILE *f_input, *f_dec;
cipher_params_t *params = (cipher_params_t *) malloc(sizeof(cipher_params_t));
unsigned char key[] = "(my 64 character length key"
unsigned char iv[] = "(my 64 character length IV)"
f_input = fopen("encrypted_file", "rb");
if (!f_input) {
/* Unable to open file for reading */
fprintf(stderr, "ERROR: fopen error: %s\n", strerror(errno));
return errno;
}
f_dec = fopen("decrypted_file", "wb");
if (!f_dec) {
/* Unable to open file for writing */
fprintf(stderr, "ERROR: fopen error: %s\n", strerror(errno));
return errno;
}
file_decrypt(params, f_input, f_dec);
fclose(f_input);
fclose(f_dec);
free(params);
return 0;
}
我收到错误:ERROR: EVP_CipherFinal_ex failed. OpenSSL error: error:06065064:lib(6):func(101):reason(100)
当我将解密功能转换为加密以加密文件然后将所有内容切换回解密该文件时,我能够成功解密文件,但不能通过命令行完成。如果有帮助,我正在使用 OpenSSL 版本 1.0.1e-fips
我正在使用加密库在 Eclipse 上运行它。
这可能是因为命令行版本与 eclipse 使用的版本不同吗?或者是否有一些通过命令行设置的其他选项我没有包含在我的解密功能中?
解决方案
我现在发现了2个问题:
- 您尚未将主要内容分配给
key
结构。iv
params
- 请记住,在您的代码中
key
,iv
应该是 32 字节和 16 字节的密钥 ad iv,而不是您发送到命令行的十六进制字符串。将命令行转换为实字节数组key
和iv
.
推荐阅读
- flutter - 无法从 Firestore Flutter 自动读取列表类型
- r - 更改图例几何类型
- javascript - 无效的网址 | 类型错误
- python - 如何在 Python Postgres 连接器中设置 Schema?
- laravel - Laravel Eloquent 中的 HAVING() 未知列
- docker - 在 docker 镜像中找不到回显
- javascript - Nuxtjs 导入 vue 组件
- javascript - 文本在 HTML/CSS 中没有正确对齐
- java - 使用 SystemPath 和 scope="system" 的外部 maven jar
- python - Plotly:如何在下拉菜单中给出不同的标签名称?