它没有重复,因为我没有问如何加密,但我问我的加密有什么问题。不喜欢这个问题你可以自由删除它。我不在乎。
我正在尝试加密一个简单的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或密钥,这是同样的错误。 所以我确实猜测c程序密钥或ivec和openssl cmd密钥或ivek有不同的东西
答案 0 :(得分:0)
我正在尝试加密一个简单的hello文本文件...
中获取了代码
我从http://openssl.org/docs/crypto/EVP_EncryptInit.html#EXAMPLES ...
以下是来自EVP Authenticated Encryption and Decryption的OpenSSL wiki的示例。它使用GCM模式,因为您经常需要/需要机密性和真实性保证,而不仅仅是机密性。
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模式,这不起作用。尚未为OpenSSL encrypt
和decrypt
子命令切入GCM。请参阅OpenSSL邮件列表中的AES-GCM failing from Command Line Interface。
如果您想知道, 是使用其他模式的有效理由,例如CBC或OFB。使用GCM模式。