C++ 使用ECB操作模式使用OpenSSL库进行AES-256加密

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-

我试图创建一个使用ECB模式的OpenSSL库的AES加密示例。很难找到任何文档,特别是关于ECB的文档,因此我举了一个使用CBC模式的代码示例,并尝试为ECB修改它。我去掉了ECB中没有包含的东西,比如初始化向量,并试图尽可能地修改代码。完成后,我在编译后遇到了一些问题:

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);