gpt4 book ai didi

c - OpenSSL 加密/解密仅解密前 7 个左右字符?

转载 作者:行者123 更新时间:2023-11-30 15:08:59 27 4
gpt4 key购买 nike

我在使用两个程序使用 openssl 加密和解密消息时遇到了一些麻烦。这两个程序编译并运行良好,但解密似乎只解密了 plaintext.txt 文件的前 7 个左右字符。

在对文件进行加密和解密后,从命令行调用如下...

./enc -i 明文.txt -o 密码.txt -p 密码

./dec i- cipher.txt -o 解密.txt -p 密码

plaintext.txt 输入是...这是需要保密的事情

decrypt.txt 输出是...这是}?w,

这里是enc.c(加密)

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

/* AES-GCM test data from NIST public test vectors */

static const unsigned char gcm_iv[] = {
0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
};

unsigned char * aes_gcm_encrypt(unsigned char *pt, long size, unsigned char *myCipher, unsigned char *out)
{
EVP_CIPHER_CTX *ctx;
int outlen, tmplen;
unsigned char outbuf[1024];
// printf("AES GCM Encrypt:\n");
// printf("Plaintext:\n");
// BIO_dump_fp(stdout, pt, size);
ctx = EVP_CIPHER_CTX_new();
/* Set cipher type and mode */
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
/* Set IV length if default 96 bits is not appropriate */
// EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(out), NULL);
/* Initialise key and IV */
EVP_EncryptInit_ex(ctx, NULL, NULL, out, gcm_iv);
/* Encrypt plaintext */
EVP_EncryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));
/* Output encrypted block */
// printf("Ciphertext:\n");
// BIO_dump_fp(stdout, outbuf, size);
/* Finalise: note get no output for GCM */
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);


EVP_CIPHER_CTX_free(ctx);
return myCipher = outbuf;
}


extern int errno;

int main(int argc, char **argv)
{

int ITERATION = 10000;
FILE * fp;
int errnum;
long size;
unsigned char *pass;
int len;
pass = argv[6];


fp = fopen(argv[2], "a+");
if (fp == NULL)
{
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("error printed by perror");
fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
}

fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);

unsigned char * buff;
buff = (unsigned char*) malloc(sizeof(unsigned char)*size + 1);
memset(buff, '\0', sizeof(unsigned char)*size + 1);
fread(buff, 1, size, fp);

int SHA1_LEN = 30;
unsigned char* out = (unsigned char*)calloc(SHA1_LEN, sizeof(unsigned char));
//int SALT_LEN = 5;
//RAND_bytes(salt, SALT_LEN);

pass = argv[6];
printf("Test print of pass: %s\n", pass);
PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), NULL, 0, ITERATION, SHA1_LEN, out);

printf("PASSWORD ENCRYPT: ");
printf("%s\n", out);

unsigned char *myCipher;

myCipher = aes_gcm_encrypt(buff, size, myCipher, out);

//printf("%s\n", myCipher);
fclose(fp);

fp = fopen(argv[4], "w+");
if (fp == NULL)
{
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("error printed by perror");
fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
}

fputs(myCipher, fp);

printf("CIPHER TEXT: %s\n", myCipher);

printf("\n");
fclose(fp);


return 0;
}

这是 dec.c(解密)

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/evp.h>


static const unsigned char gcm_iv[] = {
0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
};

unsigned char * aes_gcm_decrypt(unsigned char *pt, long size, unsigned char *myPlainText, unsigned char *out)
{
EVP_CIPHER_CTX *ctx;
int outlen, tmplen, rv;
unsigned char outbuf[1024];
//printf("AES GCM Derypt:\n");
//printf("Ciphertext:\n");
//BIO_dump_fp(stdout, pt, size);
ctx = EVP_CIPHER_CTX_new();
/* Select cipher */
EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
/* Set IV length, omit for 96 bits */
// EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL);
/* Specify key and IV */
EVP_DecryptInit_ex(ctx, NULL, NULL, out, gcm_iv);

/* Decrypt plaintext */
EVP_DecryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));
/* Output decrypted block */
// printf("Plaintext:\n");
//BIO_dump_fp(stdout, outbuf, size);

rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen);
EVP_CIPHER_CTX_free(ctx);
return myPlainText = outbuf;

}

extern int errno;

int main(int argc, char **argv)
{

int ITERATION = 10000;
FILE * fp;
int errnum;
long size;
unsigned char *pass;
int len;
pass = argv[6];


fp = fopen(argv[2], "a+");
if (fp == NULL)
{
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("error printed by perror");
fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
}

fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);

unsigned char * buff;
buff = (unsigned char*) malloc(sizeof(unsigned char)*size + 1);
memset(buff, '\0', sizeof(unsigned char)*size + 1);
fread(buff, 1, size, fp);

int SHA1_LEN = 30;
unsigned char* out = (unsigned char*)calloc(SHA1_LEN, sizeof(unsigned char));

pass = argv[6];
printf("Test print of pass: %s\n", pass);
PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), NULL, 0, ITERATION, SHA1_LEN, out);

printf("PASSWORD ENCRYPT: ");
printf("%s\n", out);

unsigned char *myPlainText;

myPlainText = aes_gcm_decrypt(buff, size, myPlainText, out);
fclose(fp);

fp = fopen(argv[4], "w+");
if (fp == NULL)
{
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("error printed by perror");
fprintf(stderr, "Error opening the file: %s\n", strerror(errnum));
}

fputs(myPlainText, fp);

printf("PLAINTEXT: %s\n", myPlainText);
printf("\n");
fclose(fp);


return 0;
}

最佳答案

如果没有详细了解 ssl,我的猜测是这些调用

EVP_EncryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));

EVP_DecryptUpdate(ctx, outbuf, &outlen, pt, sizeof(pt));

应该具有 pt 所指向的大小,而不是指针的大小。

EVP_EncryptUpdate(ctx, outbuf, &outlen, pt, ptlen);

EVP_DecryptUpdate(ctx, outbuf, &outlen, pt, ptlen);

其中 ptlen 是 pt 指向的缓冲区的大小。

查看openssl manual证实了我的猜测:

EVP_EncryptUpdate() 对输入缓冲区中的 inl 字节进行加密,并将加密版本写入输出。可以多次调用此函数来加密连续的数据 block 。写入的数据量取决于加密数据的 block 对齐:因此,写入的数据量可能是从零字节到 (inl + cipher_block_size - 1) 的任何值,因此 out 应包含足够的空间。实际写入的字节数放在outl中。

EVP_DecryptInit_ex()、EVP_DecryptUpdate()和EVP_DecryptFinal_ex()是相应的解密操作。如果启用填充并且最终 block 的格式不正确,EVP_DecryptFinal() 将返回错误代码。参数和限制与加密操作相同,除了如果启用填充,则传递给 EVP_DecryptUpdate() 的解密数据缓冲区应该有足够的空间容纳 (inl + cipher_block_size) 字节,除非密码 block 大小为 1,在这种情况下 inl 字节为足够了

关于c - OpenSSL 加密/解密仅解密前 7 个左右字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36951474/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com