C++ 使用ECB操作模式使用OpenSSL库进行AES-256加密
我试图创建一个使用ECB模式的OpenSSL库的AES加密示例。很难找到任何文档,特别是关于ECB的文档,因此我举了一个使用CBC模式的代码示例,并尝试为ECB修改它。我去掉了ECB中没有包含的东西,比如初始化向量,并试图尽可能地修改代码。完成后,我在编译后遇到了一些问题:C++ 使用ECB操作模式使用OpenSSL库进行AES-256加密,c++,c,encryption,aes,C++,C,Encryption,Aes,我试图创建一个使用ECB模式的OpenSSL库的AES加密示例。很难找到任何文档,特别是关于ECB的文档,因此我举了一个使用CBC模式的代码示例,并尝试为ECB修改它。我去掉了ECB中没有包含的东西,比如初始化向量,并试图尽可能地修改代码。完成后,我在编译后遇到了一些问题: AES-256-ECB-Encryption.cpp: In function ‘int encrypt(unsigned char*, int, unsigned char*, unsigned char*)’: AES-
AES-256-ECB-Encryption.cpp: In function ‘int encrypt(unsigned char*, int, unsigned char*, unsigned char*)’:
AES-256-ECB-Encryption.cpp:27:63: error: too few arguments to function ‘int EVP_EncryptInit_ex(EVP_CIPHER_CTX*, const EVP_CIPHER*, ENGINE*, const unsigned char*, const unsigned char*)’
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key))
错误表明我的参数太少,无法在int-encrypt函数中运行。对于int decrypt函数,我也有这个错误。我想知道这里是否有人能帮我澄清我的问题。我知道欧洲央行模式的弱点,但我仍想熟悉它。另外,我知道密钥不应该硬编码,但我只是想运行一个示例,以确保我有正确的想法。我正在OpenSSL中使用libcrypto库中的EVP对称加密和解密。如果这很重要的话,我使用的是Ubuntu 16.0.4。如果有人能解释我的问题,或者提供更多关于欧洲央行的文件,我们将不胜感激
谢谢
以下是代码的其余部分:
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
void handleErrors(void)
{
ERR_print_errors_fp(stderr);
abort();
}
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx;
int len;
int ciphertext_len;
/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
/* Initialise the encryption operation. IMPORTANT - ensure you use a key
* In this example we are using 256 bit AES (i.e. a 256 bit key).
*/
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key))
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. Further ciphertext bytes may be written at
* this stage.
*/
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
/* Initialise the decryption operation. IMPORTANT - ensure you use a key
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
*/
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key))
handleErrors();
/* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
handleErrors();
plaintext_len = len;
/* Finalise the decryption. Further plaintext bytes may be written at
* this stage.
*/
if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
plaintext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
int main (void)
{
/* A 256 bit key */
unsigned char *key = (unsigned char *)"01234567890123456789012345678901";
/* Message to be encrypted */
unsigned char *plaintext =
(unsigned char *)"This is a test.";
/* Buffer for ciphertext. Ensure the buffer is long enough for the
* ciphertext which may be longer than the plaintext, dependant on the
* algorithm and mode
*/
unsigned char ciphertext[128];
/* Buffer for the decrypted text */
unsigned char decryptedtext[128];
int decryptedtext_len, ciphertext_len;
/* Initialise the library */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
OPENSSL_config(NULL);
/* Encrypt the plaintext */
ciphertext_len = encrypt (plaintext, strlen ((char *)plaintext), key, ciphertext);
/* Do something useful with the ciphertext here */
printf("Ciphertext is:\n");
BIO_dump_fp (stdout, (const char *)ciphertext, ciphertext_len);
/* Decrypt the ciphertext */
decryptedtext_len = decrypt(ciphertext, ciphertext_len, key,
decryptedtext);
/* Add a NULL terminator. Expecting printable text */
decryptedtext[decryptedtext_len] = '\0';
/* Show the decrypted text */
printf("Decrypted text is:\n");
printf("%s\n", decryptedtext);
/* Clean up */
EVP_cleanup();
ERR_free_strings();
return 0;
}
#包括
#包括
#包括
#包括
无效句柄错误(无效)
{
错误打印错误fp(stderr);
中止();
}
整数加密(无符号字符*明文、整数明文、无符号字符*密钥、无符号字符*密文)
{
EVP_CIPHER_CTX*CTX;
内伦;
整数密文;
/*创建并初始化上下文*/
如果(!(ctx=EVP_CIPHER_ctx_new())句柄错误();
/*初始化加密操作。重要信息-确保使用密钥
*在本例中,我们使用256位AES(即256位密钥)。
*/
如果(1!=EVP_EncryptInit_ex(ctx,EVP_aes_256_ecb(),NULL,key))
handleErrors();
/*提供要加密的消息,并获取加密输出。
*如有必要,可多次调用EVP_EncryptUpdate
*/
如果(1!=EVP_EncryptUpdate(ctx、密文和len、明文、明文))
handleErrors();
密文_len=len;
/*完成加密。进一步的密文字节可写入
*这个阶段。
*/
如果(1!=EVP_EncryptFinal_ex(ctx、密文+len和len))句柄错误();
密文_len+=len;
/*清理*/
无密码(CTX)的执行副总裁;
返回密文;
}
整数解密(无符号字符*密文,整数密文,无符号字符*密钥,无符号字符*明文)
{
EVP_CIPHER_CTX*CTX;
内伦;
int纯文本;
/*创建并初始化上下文*/
如果(!(ctx=EVP_CIPHER_ctx_new())句柄错误();
/*初始化解密操作。重要信息-确保使用密钥
*在本例中,我们使用256位AES(即256位密钥)
*/
if(1!=EVP_DecryptInit_ex(ctx,EVP_aes_256_ecb(),NULL,key))
handleErrors();
/*提供要解密的消息,并获得明文输出。
*如有必要,可多次调用EVP_DecryptUpdate
*/
if(1!=EVP_DecryptUpdate(ctx、明文和len、密文、密文_len))
handleErrors();
明文_len=len;
/*完成解密。可在以下位置写入更多明文字节:
*这个阶段。
*/
如果(1!=EVP_decryptofinal_ex(ctx,明文+len,&len))handleErrors();
明文_len+=len;
/*清理*/
无密码(CTX)的执行副总裁;
返回纯文本;
}
内部主(空)
{
/*256位密钥*/
无符号字符*键=(无符号字符*)“012345678901234567890123456789012345678901”;
/*要加密的消息*/
无符号字符*纯文本=
(无符号字符*)“这是一个测试。”;
/*密文缓冲区。请确保缓冲区足够长,以便
*可能比明文长的密文,取决于
*算法与模式
*/
无符号字符密文[128];
/*解密文本的缓冲区*/
未签名字符解密文本[128];
整数解密文本,密文;
/*初始化库*/
错误加载加密字符串();
OpenSSL_添加_所有算法();
OPENSSL_配置(空);
/*加密明文*/
密文=加密(明文,strlen((char*)明文),密钥,密文);
/*在这里用密文做些有用的事情*/
printf(“密文为:\n”);
BIO_dump_fp(标准输出,(常量字符*)密文,密文长度);
/*解密密文*/
decryptedtext\u len=解密(密文,密文,密钥,
解密文本);
/*添加空终止符。应为可打印文本*/
decryptedtext[decryptedtext_len]='\0';
/*显示解密的文本*/
printf(“解密文本为:\n”);
printf(“%s\n”,解密文本);
/*清理*/
EVP_cleanup();
ERR_free_strings();
返回0;
}
该函数接受5个参数,将NULL
传递给iv
参数
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
从:
作为老绝地大师,@zaph平静地指示@akfe79“相信错误信息”".有趣的组合,不安全的ECB模式和超高的AES-256。不要使用ECB模式,它是不安全的,请看,向下滚动到企鹅。但是你知道这一点,也不在乎?错误消息指出,当你应该通过5时,你将4个参数传递给EVP_EncryptInit_ex。是的,我修复了它。在我摆脱t之后,我完全掩盖了它他说:“我应该在那里加一个空值。谢谢。另外,我这样做只是为了学习zaph。我意识到它的缺陷,但我仍然想了解更多关于ECB包括的所有模式。等等——这不是应该是“相信你的直觉”吗?这不适用于参数列表吗?我发现:“正如老绝地大师欧比-万·克诺比平静地指示卢克“相信原力”。:-)注意到的那样,我正在回忆带防爆罩的训练球和头盔降落场景……是的,这修复了它,现在它工作得很好。感谢你的帮助;我应该知道,当我移除iv指针时,我必须放置一个占位符。
int EVP_EncryptInit_ex( EVP_CIPHER_CTX *ctx,
const EVP_CIPHER *type,
ENGINE *impl,
unsigned char *key,
unsigned char *iv);