在C ++中使用OpenSSL使用AES128加密字符串时出错

Noe Cano

我在CBC模式下使用OpenSSL库和AES 128算法生成的加密消息的最后一个字符遇到问题,这些是我正在使用的数据:

Message in Hex = "7b22494443223a2232363930393439376434222c22444553223a2256656e74616d656e7564656f222c22414d4f223a3530302c22444154223a313530383233303035383730362c22524546223a302c22434f4d223a312c22545950223a31392c2276223a7b224e414d223a2252616661656c56616c656e7a75656c614172656e6173222c22414343223a2235383732313233343536373836303132222c2242414e223a34303132372c22545943223a332c22444556223a22353532373139323132382f30227d7da"
Key128 in Hex = "dadf11e74d014a62d73ccadd9591442a"
Initialization Vector in Hex = "cab9da8940cd7dc9510c7249fe47c6e6"

这是我正在使用的代码:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <math.h>
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <locale>

#include <openssl/aes.h>
#include <openssl/des.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>

using namespace std;

/* AES key for Encryption and Decryption */
const static unsigned char aes_key[16]={0xda, 0xdf, 0x11, 0xe7, 0x4d, 0x01, 0x4a, 0x62, 0xd7, 0x3c, 0xca, 0xdd, 0x95, 0x91, 0x44, 0x2a};

/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len)
{
    printf("%s : ",tittle);
    const unsigned char * p = (const unsigned char*)data;
    int i = 0;

    for (; i<len; ++i)
    {
        printf("%02X ", *p++);
    }

    printf("\n");
}

int main( )
{
    /* Input data to encrypt */
    unsigned char enc_out[235]={0x7b, 0x22, 0x49, 0x44, 0x43, 0x22, 0x3a, 0x22, 0x32, 0x36, 0x39, 0x30, 0x39, 0x34, 0x39, 0x37, 0x64, 0x34, 0x22, 0x2c, 0x22, 0x44, 0x45, 0x53, 0x22, 0x3a, 0x22, 0x56, 0x65, 0x6e, 0x74, 0x61, 0x6d, 0x65, 0x6e, 0x75, 0x64, 0x65, 0x6f, 0x22, 0x2c, 0x22, 0x41, 0x4d, 0x4f, 0x22, 0x3a, 0x35, 0x30, 0x30, 0x2c, 0x22, 0x44, 0x41, 0x54, 0x22, 0x3a, 0x31, 0x35, 0x30, 0x38, 0x32, 0x33, 0x30, 0x30, 0x35, 0x38, 0x37, 0x30, 0x36, 0x2c, 0x22, 0x52, 0x45, 0x46, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x43, 0x4f, 0x4d, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x54, 0x59, 0x50, 0x22, 0x3a, 0x31, 0x39, 0x2c, 0x22, 0x76, 0x22, 0x3a, 0x7b, 0x22, 0x4e, 0x41, 0x4d, 0x22, 0x3a, 0x22, 0x52, 0x61, 0x66, 0x61, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x65, 0x6e, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x41, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x22, 0x2c, 0x22, 0x41, 0x43, 0x43, 0x22, 0x3a, 0x22, 0x35, 0x38, 0x37, 0x32, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x36, 0x30, 0x31, 0x32, 0x22, 0x2c, 0x22, 0x42, 0x41, 0x4e, 0x22, 0x3a, 0x34, 0x30, 0x31, 0x32, 0x37, 0x2c, 0x22, 0x54, 0x59, 0x43, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x44, 0x45, 0x56, 0x22, 0x3a, 0x22, 0x35, 0x35, 0x32, 0x37, 0x31, 0x39, 0x32, 0x31, 0x32, 0x38, 0x2f, 0x30, 0x22, 0x7d, 0x7d, 0xa};

    /* Init vector */
    unsigned char iv[16]={0xca, 0xb9, 0xda, 0x89, 0x40, 0xcd, 0x7d, 0xc9, 0x51, 0x0c, 0x72, 0x49, 0xfe, 0x47, 0xc6, 0xe6};
    //memset(iv, 0x00, AES_BLOCK_SIZE);

    /* Buffers for Encryption and Decryption */
    unsigned char dec_out[400];
    unsigned char aux_out[400];

    memset(dec_out, 0, sizeof(dec_out));
    memset(aux_out, 0, sizeof(aux_out));

    /* AES-128 bit CBC Encryption */
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, sizeof(aes_key)*8, &enc_key);
    AES_cbc_encrypt(enc_out, dec_out, sizeof(enc_out), &enc_key, iv, AES_ENCRYPT);
    /* AES-128 bit CBC Decryption */
    memset(iv, 0x00, AES_BLOCK_SIZE); // don't forget to set iv vector again, else you can't decrypt data properly
    AES_set_decrypt_key(aes_key, sizeof(aes_key)*8, &dec_key); // Size of key is in bits
    AES_cbc_encrypt(dec_out, aux_out, sizeof(enc_out), &dec_key, iv, AES_DECRYPT);

    /* Printing and Verifying */
    print_data("\n Original ",enc_out, sizeof(enc_out)); // you can not print data as a string, because after Encryption its not ASCII

    print_data("\n Encrypted",dec_out, sizeof(enc_out));

    print_data("\n Decrypted",aux_out, sizeof(dec_out));

    return 0;
}

显然,只有链的末端是不正确的末端字符(最后32个字符),其余的都很好,我进行了一些研究,所有内容均指向文本填充的类型,但根据我所读的内容,已经用PKCS5填充(实际上是我需要的填充),所以我看不到错误是什么。

The Correct Encryption = EFC063DD33406D424D359809695D0B1E2D65027E803962C6A115DF7CCABEEB0C8C358830E556ED23943FA4F02E6461D235EF913CFCE5519F7CE2279DD07D3C4054D045827D5D7D9FE94DA3C5B718A24E79539B3FFC1E68E4C3FF441EEA176F61EE3D7B33B622E3069D95815F6407FBC79342BB972A2DDE4E50FDE9302BDE4409B7D2BD388AB6A043B9EF236D982937D8537F954564FF4134BD8A6EAB994FE4C29E9DC4E54D53A561A4688C45C90961EDB1763B6EF6C86B593C7E16FDF35C49CE16B1E6948BB1EAE6A8692326A019960B

The Output of the Program = EFC063DD33406D424D359809695D0B1E2D65027E803962C6A115DF7CCABEEB0C8C358830E556ED23943FA4F02E6461D235EF913CFCE5519F7CE2279DD07D3C4054D045827D5D7D9FE94DA3C5B718A24E79539B3FFC1E68E4C3FF441EEA176F61EE3D7B33B622E3069D95815F6407FBC79342BB972A2DDE4E50FDE9302BDE4409B7D2BD388AB6A043B9EF236D982937D8537F954564FF4134BD8A6EAB994FE4C29E9DC4E54D53A561A4688C45C90961EDB1763B6EF6C86B593C7E16FDF35C49CE608E3F73FC8E3DDF1D3BCF40B3DFACD00B732A9FCC10F6E0FB18E126A1C21A082D7A4F053F131A9329474D

我了解该代码有很多改进,我没有考虑解密密码,但是目前我不需要它。

托帕可

enc_out-阵列的尺寸为235个字节,但只初始化明确了200个字节,即剩余的字节隐含初始化0x00-值。这对应于长度为240字节(= 15 x 16字节)的密文。因此,当前代码返回的密文长度为240个字节,其后三个块为:

608E3F73FC8E3DDF1D3BCF40B3DFACD0 0B732A9FCC10F6E0FB18E126A1C21A08 2D7A4F053F131A9329474DE44DA772BC

这对应于带有0x00-values的隐式填充发布的密文中缺少最后5个字节,这是因为明文的长度(而不是密文)用于输出。

最有可能只应加密前200个字节。这将与长度为208个字节(= 13 x 16个字节)的密文相对应,这恰好是预期密文的长度为此,enc_out必须将-array的大小从235减小到200,甚至更好,根本不应该明确指定大小。

然后,生成一个短了两个块的密码密文,但其他方面相同,这与预期的密文仅在最后一个密文不同,后者仅由缺少PKCS7填充引起。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在c#中使用AES 128位加密字符串?

使用C ++,Openssl和AES加密和解密字符串

在C中使用字符串数组时出错

C#中使用AES 256位ECB的意外加密字符串

C-使用AES加密和解密字符串

尝试在C ++中使用Boost Regex Match从字符串转换为Int时出错

在C#中使用IEnumerable和字符串进行转换时出错

使用openssl C进行AES(AES-IGE-128,AES-IGE-192,AES-IGE-256)加密/解密

使用高级加密标准算法(AES)在Typescript中加密字符串并在C#中解密

使用Objective C在iOS中使用公钥加密或签名字符串

在 c 中使用字符串

使用C#中的PFX文件加密字符串

无法使用 XOR C crypter 加密长字符串

无法从目标C解密AES加密的字符串

在Objective-C中解密OpenSSL加密的字符串

如何在 Javascript 中使用 AES-128-CBC 算法加密字符串?

使用 asm 函数修改 C 结构中分配的字符串时出错

当分别使用nodejs和c进行AES-128-cbc加密时,使用相同的密钥和IV,但结果不同

在C#中使用Assert.AreEqual()比较字符串时何时传递文化

c#中使用字符串时引用类型和值类型之间的区别

在C#中使用字符串调用方法时,“对象与目标类型不匹配”

在C中使用concat字符串指针时如何避免内存泄漏

为什么在C ++中使用字符串时没有输出?

在C#中使用AESManaged进行AES加密

使用Bison / Flex时使用C字符串

在iOS中使用AES / CBC / PKCS7Padding 128位算法在Android中加密的解密字符串的问题

在C中使用指针交换字符串函数

在C中使用分隔符分割字符串

在数组中使用C字符串