gpt4 book ai didi

c - 在 C 中使用 OpenSSL API 进行加密

转载 作者:行者123 更新时间:2023-11-30 17:14:52 29 4
gpt4 key购买 nike

它不重复,因为我不是问如何加密,而是问我的加密出了什么问题。不喜欢这个问题,您可以随意删除它。我不在乎。

我正在尝试加密一个简单的 hello 文本文件。

这是我加密数据的代码。

int encrypt(EVP_CIPHER_CTX *ctx, FILE *ifp,FILE *ofp)
{
int bytes_read, bytes_written, enc_bytes,tlen;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char encdata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
while (1) {
bytes_read = fread(indata, 1, AES_BLOCK_SIZE, ifp);

if (EVP_EncryptUpdate (ctx, encdata, &enc_bytes, indata, bytes_read) != 1)
{
printf ("error in encrypt update\n");
return -1;
}
printf ("INPUT\n");
print_memory(indata, bytes_read);
if (EVP_EncryptFinal (ctx, encdata + enc_bytes, &tlen) != 1)
{
printf ("error in encrypt final\n");
return -1;
}

printf ("OUTPUT\n");
print_memory(encdata,enc_bytes+tlen);
bytes_written = fwrite(encdata, 1,enc_bytes + tlen, ofp);
if (bytes_read < AES_BLOCK_SIZE)
break;
}

这是 key 和ivec,我用于初始化

unsigned char ckey[] =  {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
unsigned char ivec[] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};


EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (&ctx);
EVP_EncryptInit (&ctx, EVP_bf_cbc (), ckey, ivec);

这是十六进制输出的加密数据 24 47 50 58 93 0B 04 9C D5 54 65 93 D1 6B AD 5A

但是当我尝试使用 openSSL cmd 解码数据时我收到以下错误

anshul:~/> openssl aes-128-cbc  -d  -in  otext  -K 000102030405060708090A0B0C0D0E0F -iv 000102030405060708090A0B0C0D0E0F -nosalt
bad decrypt
3075450556:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:529:

如果我使用错误的 ivec 或 key ,这与我得到的错误相同。所以我确实猜测 c 程序 key 或 ivec 和 openssl cmd key 或 ivek 中有不同的东西

最佳答案

I am trying to encrypt one simple hello text file...
I took code from http://openssl.org/docs/crypto/EVP_EncryptInit.html#EXAMPLES...

以下是 OpenSSL wiki EVP Authenticated Encryption and Decryption 上的示例。它使用 GCM 模式,因为您经常想要/需要 secret 性真实性保证,而不仅仅是 secret 性

OpenSSL 例程处理内存中的字节字符串。因此,您必须读取该文件并向 OpenSSL 函数提供一个字节字符串。

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *aad,
int aad_len, unsigned char *key, unsigned char *iv,
unsigned char *ciphertext, unsigned char *tag)
{
EVP_CIPHER_CTX *ctx;

int len, ciphertext_len;

/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the encryption operation. */
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
handleErrors();

/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
handleErrors();

/* Initialise key and IV */
if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();

/* Provide any AAD data. This can be called zero or more times as
* required
*/
if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
handleErrors();

/* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
handleErrors();
ciphertext_len = len;

/* Finalise the encryption. Normally ciphertext bytes may be written at
* this stage, but this does not occur in GCM mode
*/
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;

/* Get the tag */
if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
handleErrors();

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

return ciphertext_len;
}

解密例程:

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *aad,
int aad_len, unsigned char *tag, unsigned char *key, unsigned char *iv,
unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;
int len, plaintext_len, ret;

/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the decryption operation. */
if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
handleErrors();

/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
handleErrors();

/* Initialise key and IV */
if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();

/* Provide any AAD data. This can be called zero or more times as
* required
*/
if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
handleErrors();

/* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
handleErrors();
plaintext_len = len;

/* Set expected tag value. Works in OpenSSL 1.0.1d and later */
if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
handleErrors();

/* Finalise the decryption. A positive return value indicates success,
* anything else is a failure - the plaintext is not trustworthy.
*/
ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

if(ret > 0)
{
/* Success */
plaintext_len += len;
return plaintext_len;
}
else
{
/* Verify failed */
return -1;
}
}
<小时/>
anshul:~/> openssl aes-128-cbc -d -in ...

对于 GCM 模式,这不起作用。 GCM 尚未切入 OpenSSL encryptdecrypt 子命令。请参阅AES-GCM failing from Command Line Interface在 OpenSSL 邮件列表中。

如果您想知道,这不是使用不同模式(例如 CBC 或 OFB)的正当理由。使用 GCM 模式。

关于c - 在 C 中使用 OpenSSL API 进行加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30151686/

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