首页 > 编程语言 >20.3 OpenSSL 对称AES加解密算法

20.3 OpenSSL 对称AES加解密算法

时间:2023-10-30 13:32:02浏览次数:38  
标签:AES 20.3 加密 加解密 aes unsigned char key

AES算法是一种对称加密算法,全称为高级加密标准(Advanced Encryption Standard)。它是一种分组密码,以128比特为一个分组进行加密,其密钥长度可以是128比特、192比特或256比特,因此可以提供不同等级的安全性。该算法采用了替代、置换和混淆等技术,以及多轮加密和密钥扩展等机制,使得其加密效果优秀,安全性高,被广泛应用于各种领域中,如数据加密、文件加密、网络安全等。

AES算法加密和解密使用的密钥是相同的,该算法加密和解密速度较快,适用于对大量数据进行加密解密的场景。在实际应用中,通常采用混合加密方式,即使用RSA算法加密对称加密算法中的密钥,再使用对称加密算法加密数据,以保证数据的机密性和加密解密的效率。

AES算法常用两种加密模式,即CBC和ECB模式,它们分别具有不同的优缺点。

  • ECB(Electronic Codebook,电子密码本)模式是最简单的分组密码工作模式,将每个明文块独立加密,同样的密钥加密同样的明文块得到的密文也是一样的,因此容易被攻击者利用重复的密文进行分析破解。ECB模式加密效率高,适用于短报文加密,但不适用于长报文加密。

  • CBC(Cipher Block Chaining,密码块链)模式是一种分组密码工作模式,先将明文分组,然后对每个分组进行加密,加密时使用上一块密文作为输入,因此相同的明文块在不同位置上得到的密文是不同的,可以防止被攻击者利用重复的密文进行分析破解。CBC模式加密效率较低,但适用于长报文加密,因为不同的明文块之间互相影响,增加了安全性。

在实际应用中,通常采用CBC模式进行加密,因为它比ECB模式更安全,但加密效率较低。此外,还有其他的加密模式,如CFB、OFB、CTR等,不同的加密模式适用于不同的场景,需要根据实际需求进行选择。

OpenSSL库提供了对AES加密的支持,但在使用时读者还是需要自行封装一些通用加解密函数,如下代码片段是笔者常用的一些函数总结,其中aes_cbc_encrypt函数用于使用CBC模式对特定字符串加密,aes_cbc_decrypt则使用CBC模式对字符串进行解密,第二个函数AES函数则是使用OpenSSL库默认的加解密函数二次封装实现的。

#include <iostream>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/pem.h>

extern "C"
{
#include <openssl/applink.c>
}

#pragma comment(lib,"libssl_static.lib")
#pragma comment(lib,"libcrypto.lib")

// CBC模式加密
int aes_cbc_encrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
        return 0;

    unsigned char iv[AES_BLOCK_SIZE];
    for (int i = 0; i < AES_BLOCK_SIZE; ++i)
        iv[i] = 0;

    AES_KEY aes;
    if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }
    int len = strlen(in);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);
    return 1;
}

// CBC模式解密
int aes_cbc_decrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
        return 0;

    // 加密的初始化向量
    unsigned char iv[AES_BLOCK_SIZE];

    // iv一般设置为全0
    for (int i = 0; i < AES_BLOCK_SIZE; ++i)
        iv[i] = 0;

    AES_KEY aes;
    if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }
    int len = strlen(in);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
    return 1;
}

// 将加密与解密整合在一起
void AES(unsigned char* InBuff, unsigned char* OutBuff, unsigned char* key, char* Type)
{
    if (strcmp(Type, "encode") == 0)
    {
        AES_KEY AESEncryptKey;
        AES_set_encrypt_key(key, 256, &AESEncryptKey);
        AES_encrypt(InBuff, OutBuff, &AESEncryptKey);
    }
    else if (strcmp(Type, "decode") == 0)
    {
        AES_KEY AESDecryptKey;
        AES_set_decrypt_key(key, 256, &AESDecryptKey);
        AES_decrypt(InBuff, OutBuff, &AESDecryptKey);
    }
}

有了上述算法封装,接下来笔者将依次演示这几种不同的加密函数是如何被应用的,首先简单介绍一下aes_cbc_encryptaes_cbc_decrypt这两个函数都是自己封装的AES加解密算法,这两个算法参数传递保持一致,第一个参数都是指定需要加密的缓冲区,第二个参数则是指定加密所使用的key,第三个参数是处理后的结果。

int main(int argc, char* argv[])
{
  char szBuffer[1024] = "hello lyshark";
  char szDst[1024] = { 0 };
  char szSrc[1024] = { 0 };

  // 计算一串密钥
  char key[AES_BLOCK_SIZE] = { 0 };
  for (int x = 0; x < AES_BLOCK_SIZE; x++)
  {
    key[x] = 32 + x;
  }

  // AES加密
  if (aes_cbc_encrypt(szBuffer, key, szDst) != 0)
  {
    std::cout << "加密后长度: " << strlen(szDst) << std::endl;
  }

  // AES解密
  if (aes_cbc_decrypt(szDst, key, szSrc) != 0)
  {
    std::cout << "解密内容: " << szSrc << std::endl;
  }

  system("pause");
  return 0;
}

上述代码片段则是通过AES实现对数据加解密处理的功能,如下是这段代码的输出效果;

第二种调用方式是采用API实现,其中的AES函数,通过AES_set_encrypt_key设置加密密钥,并直接调用AES_encrypt实现数据加密,反之,通过AES_set_decrypt_key设置解密密钥,并调用AES_decrypt解密,这段代码调用方式如下所示;

int main(int argc, char* argv[])
{
  unsigned char Buffer[1024] = "hello lyshark";
  unsigned char EncodeBuf[1024] = { 0 };
  unsigned char DecodeBuf[1024] = { 0 };
  unsigned char aes_key[32] = { 0 };

  // 随机生成密钥
  for (int x = 0; x < 32; x++)
  {
    int ch = rand() % 5;
    aes_key[x] = (char)ch;
  }

  AES(Buffer, EncodeBuf, (unsigned char *)aes_key, (char*)"encode");
  std::cout << "加密数据长度: " << strlen((char *)EncodeBuf) << std::endl;

  AES(EncodeBuf, DecodeBuf, (unsigned char*)aes_key, (char*)"decode");
  std::cout << "解密数据: " << DecodeBuf << std::endl;

  system("pause");
  return 0;
}

如上代码,通过调用AES函数时,传入encode实现数据加密,传入decode实现数据解密,如下图所示;

标签:AES,20.3,加密,加解密,aes,unsigned,char,key
From: https://blog.51cto.com/lyshark/8088083

相关文章

  • 20.3 OpenSSL 对称AES加解密算法
    AES算法是一种对称加密算法,全称为高级加密标准(AdvancedEncryptionStandard)。它是一种分组密码,以128比特为一个分组进行加密,其密钥长度可以是128比特、192比特或256比特,因此可以提供不同等级的安全性。该算法采用了替代、置换和混淆等技术,以及多轮加密和密钥扩展等机制,使得其加密......
  • 20.2 OpenSSL 非对称RSA加解密算法
    RSA算法是一种非对称加密算法,由三位数学家Rivest、Shamir和Adleman共同发明,以他们三人的名字首字母命名。RSA算法的安全性基于大数分解问题,即对于一个非常大的合数,将其分解为两个质数的乘积是非常困难的。RSA算法是一种常用的非对称加密算法,与对称加密算法不同,RSA算法使用一对非对......
  • 20.2 OpenSSL 非对称RSA加解密算法
    RSA算法是一种非对称加密算法,由三位数学家Rivest、Shamir和Adleman共同发明,以他们三人的名字首字母命名。RSA算法的安全性基于大数分解问题,即对于一个非常大的合数,将其分解为两个质数的乘积是非常困难的。RSA算法是一种常用的非对称加密算法,与对称加密算法不同,RSA算法使用一对非......
  • AES加密
    关于AESAES属于分组加密算法,明文长度固定为128位,密钥长度可以为128、192、256位。本文以明文长度128位,密钥长度128位的AES进行实现。AES加密解密python实现#S-Box的预定义值,用于替代输入字节。256s_box=(0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,......
  • Lattice .bek档案AES加密解密
    //BEK.h#ifndef__BEK_H__#define__BEK_H__#include<stdio.h>#include<stdlib.h>#include<stdbool.h>/////////////////////////////////////////////////////////////////////////////CRCTables////////////////////////////////////////////......
  • 爬虫加解密分析
    1、找到加密的接口地址,通过加密的接口地址全局搜索2、通过打断点的方式,找到加密串;3、找到用的是哪种加密方式,找到对应方式的加密语言加解密即可。     参考链接:https://blog.csdn.net/zhinian1204/article/details/124112512https://blog.csdn.net/cuilun000/a......
  • app直播源码,android AES加密解密实现
     app直播源码,androidAES加密解密实现importandroid.util.Base64;importandroid.util.Log; importjava.security.Key; importjavax.crypto.Cipher;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESedeKeySpec;importjavax.crypto.spec.IvParameterSpe......
  • Mybatis自定义TypeHandler完成字段加解密And枚举数据处理
    Mybatis自定义TypeHandler完成字段加解密And枚举数据处理新增And查询对枚举数据处理定义枚举@GetterpublicenumUserEnum{HOLD_A_POST("在职",10),RESIGN("离职",20);privateStringname;privateIntegervalue;UserEnum(Stringname,......
  • AES key — encoded in the machine readable zone of a European ePassport
    AESkey—encodedinthemachinereadablezoneofaEuropeanePassport题目地址AESkey—encodedinthemachinereadablezoneofaEuropeanePassport解题过程第一步:补全给出的密钥通过查阅题目附录里提到的文档,可以找到校验位的具体机制,依据解释可求出初始密钥"?......
  • maestro studio 简化编写测试worflow 的工具
    对于自己编写workflow有时可能会比较复杂,maestrostudio提供了基于ai的强大能力,同时可以实时模拟器的页面与web集成对于测试人员来说是一个很不错的选择,很值得看看,同时因为maestrostudio也是开源的,代码上也值得学习参考参考资料https://maestro.mobile.dev/getting-started......