前序

AES介绍
不多说了,可以度娘。。。
贴点传送门,都是优秀的参考文献
链接:https://blog.csdn.net/weixin_45303938/article/details/108089078
实用贴——分组加密的常用工作模式
链接:https://blog.csdn.net/duanxingheng/article/details/11730617
OPENSSL库的使用-AES篇

实用函数

贴一下头文件,有兴趣的都应该去翻openssl/include
#include <openssl/aes.h> //aes加密

# define AES_ENCRYPT     1
# define AES_DECRYPT     0

/*
* Because array size can't be a const in C, the following two are macros.
* Both sizes are in bytes.
*/

# define AES_MAXNR 14
# define AES_BLOCK_SIZE 16
//	AES默认块长 128bits,大部分代码会调用  AES_BLOCK_SIZE  去初始化

typedef struct aes_key_st AES_KEY;

const char *AES_options(void);

int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                      AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
                      AES_KEY *key);
/*
这两个函数分别用于加解密的密钥生成
@const unsigned char *userKey    约定密码
@const int bits					密码长度  分别对应128 、 192 、 256   
  		注意这里是bits,所以是输入密码长度*8,也就是16位长度密码对应128bits
@AES_KEY *key				    生成密体
*/


void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
                   const AES_KEY *key, const int enc);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
                   size_t length, const AES_KEY *key,
                   unsigned char *ivec, const int enc);

/*
这两个函数分别用于加解密的密钥生成
@in              需要加密/解密的数据
@out            计算后输出的数据
@length 		数据长度
@key 			密钥体AES_KEY 
@ivec   		初始向量(一般为16字节全0)
@enc   			AES_ENCRYPT 代表加密, AES_DECRYPT代表解密;
*/

C++代码

可以使用#include <openssl/aes.h> 去进行加密处理

// AES加密
std::string aes_encode(std::string& data, std::string& passwd)
{

  
  int dataLen = data.length();
  int nPadd = AES_BLOCK_SIZE - dataLen % AES_BLOCK_SIZE;    //pkcs7padding,缺N位就补N个N
  data.append(size_t(nPadd), char(nPadd));

  dataLen = data.length();                                 //补齐之后的数据长度
  unsigned char ivb[AES_BLOCK_SIZE];           			   //一般16位,关于IV这里用的是全‘0’填充
  memset(&ivb, '0', AES_BLOCK_SIZE);		//有兴趣增加密码安全的可以置换或者随机IV随加密结果输出
  unsigned char buf[dataLen];
  memset(&buf, 0, dataLen);

  AES_KEY key;
  AES_set_encrypt_key((unsigned const char *)(passwd.c_str()), 128, &key);       //*8 int bit 设置密钥

  AES_cbc_encrypt((unsigned const char *)(data.c_str()), buf, dataLen, &key, &(ivb[0]), AES_ENCRYPT); 
  //enc: 加密/解密模式,AES_ENCRYPT,加密;AES_DECRYPT,解密;

  auto base64Out = base64_encode(buf, dataLen);				//这个不是加密过程,普通base64

  
  return base64Out;
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];
  
  while (in_len--) {
      char_array_3[i++] = *(bytes_to_encode++);
      if (i == 3) {
          char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
          char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
          char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
          char_array_4[3] = char_array_3[2] & 0x3f;
          
          for(i = 0; (i <4) ; i++)
              ret += base64_chars[char_array_4[i]];
          i = 0;
      }
  }
  
  if (i)
  {
      for(j = i; j < 3; j++)
          char_array_3[j] = '\0';
      
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;
      
      for (j = 0; (j < i + 1); j++)
          ret += base64_chars[char_array_4[j]];
      
      while((i++ < 3))
          ret += '=';
      
  }
  
  return ret;
  
}

openssl-EVP加密框架

好吧,等我试了几次死磕出了加密方法之后,小伙伴突然说openssl有个EVP框架,实现了加解密过程。。。早说嘛,不过说实话实际用上之后觉得好像比自己写还复杂,可能对于ECB和CBC模式来说大材小用了,期望RSA会简单还有流式加解密模式。

#include <openssl/evp.h>

std::string aes_encodeV1(std::string& data, std::string& passwd)
{
  EVP_CIPHER_CTX *ctx;
  int outlen = 0;
  int encLen = 0;
  ctx = EVP_CIPHER_CTX_new();
  int dataLen = data.length();

  int nPadd = AES_BLOCK_SIZE - dataLen % AES_BLOCK_SIZE;    //pkcs7padding
  data.append(size_t(nPadd), char(nPadd));
  dataLen = data.length();
  unsigned char ivb[AES_BLOCK_SIZE];
  memset(&ivb, '0', AES_BLOCK_SIZE);
  unsigned char buf[dataLen];
  memset(&buf, 0, dataLen);

  EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, (unsigned const char *)(passwd.c_str()), ivb, 1);
  EVP_CipherUpdate(ctx, buf, &outlen, (unsigned const char *)(data.c_str()), dataLen);
  encLen = outlen;
  EVP_CipherFinal(ctx, buf+outlen, &outlen);
  encLen += outlen;
  EVP_CIPHER_CTX_free(ctx);

  auto base64Out = base64_encode(buf, encLen);	
  return base64Out;
}

python验证代码

#!/usr/bin/env python3
#
# This is a simple script to encrypt a message using AES
# with CBC mode in Python 3.
# Before running it, you must install pycryptodome:
#
# $ python -m pip install PyCryptodome
#
# Author.: silverzzq
# Date...: 2021-03-25
##
from base64 import b64decode

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

class AESCipher:
    def __init__(self, key):
        self.key = key.encode('utf8')

    def encrypt(self, data):
        iv = ""
        iv = iv.ljust(16,'0').encode('utf-8')
        self.cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return b64encode(self.cipher.encrypt(pad(data.encode('utf-8'), 
            AES.block_size)))
        #pad中默认的padding模式就是pkcs7padding


if __name__ == '__main__':
    msg = "12345678123456781234567812345678"
    pwd = "1234567812345678"
    print('Ciphertext:', AESCipher(pwd).encrypt(msg).decode('utf-8'))
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐