使用Crypto++库的CBC模式实现加密(二)

前面已经有一篇介绍使用Crypto++库实现的加密的文章了,但是代码中考虑的不完全,所以就重新发了个二

C++封装:

#include "zyaes.h"
#include <string.h>
#include <stdio.h>

using namespace CryptoPP;

CZYAes::CZYAes()
{
    byte byteKey[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x01,0x02, 0x03,0x04,0x05,0x06,0x07,0x08,
                0x01,0x02, 0x03,0x04,0x05,0x06,0x07,0x08, 0x01,0x02, 0x03,0x04,0x05,0x06,0x07,0x08};
    byte byteIv[] = {0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04, 0x01,0x02, 0x03,0x04,0x01,0x02,0x03,0x04};
    memcpy(m_arrByteKey, byteKey, sizeof(byte) * 32);
    memcpy(m_arrByteIv, byteIv, sizeof(byte) * 16);
    m_nKeyLen = 32;
}

CZYAes::~CZYAes()
{
}

// set key and iv
void CZYAes::SetKey(std::string strKey, std::string strIv)
{
    int nKeyLen = 0;
    int nIvLen = 0;
    memset(m_arrByteKey, 0, sizeof(byte) * 32);
    memset(m_arrByteIv, 0, sizeof(byte) * 16);

    if (strKey.length() >= 32)
    {
        nKeyLen = 32;
    }
    else
    {
        nKeyLen = strKey.length();
    }
    memcpy(m_arrByteKey, strKey.c_str(), sizeof(byte) * nKeyLen);

    if (!strIv.empty())
    {
        if (strIv.length() >= 16)
        {
            nIvLen = 16;
        }
        else
        {
            nIvLen = strIv.length();
        }
        memcpy(m_arrByteIv, strIv.c_str(), sizeof(byte) * nIvLen);
    }
}

// encrypt
std::string CZYAes::Encrypt(const std::string &strText)
{
    std::string strCipher;
    CBC_Mode<AES>::Encryption aesEncryptor(m_arrByteKey, m_nKeyLen, m_arrByteIv);
    StringSource(strText, true, new StreamTransformationFilter(aesEncryptor, new StringSink(strCipher)));

    std::string strEncoded;
    StringSource s2(strCipher, true,
        new HexEncoder(
            new StringSink(strEncoded)
        ) // HexEncoder
    ); // StringSource
    return strEncoded;
}

// decrypt
std::string CZYAes::Decrypt(const std::string &strCipher)
{
    std::string strDecoded;
    StringSource s2(strCipher, true,
        new HexDecoder(
            new StringSink(strDecoded)
        ) // HexEncoder
    ); // StringSource

    std::string strText;
    CBC_Mode<AES>::Decryption aesEncryptor(m_arrByteKey, m_nKeyLen, m_arrByteIv);
    StringSource(strDecoded, true, new StreamTransformationFilter(aesEncryptor, new StringSink(strText)));

    return strText;
}

实现文件

头文件

C封装:

//*****************************************************************************
//@FileName    : aes256.cpp
//@Version    : v1.0.0
//@Author    : xiaoc
//@Date        : 2015/03/13
//*****************************************************************************
#include "zyaes.h"
#include "zyaes256.h"
using namespace std;

string Encrypt(const string &strText, const string &strKey/* = "" */)
{
    std::string strCipher;
    int nLen = 0;
    CZYAes aes;

    if (!strKey.empty())
    {
        aes.SetKey(strKey, "");
    }
    strCipher = aes.Encrypt(strText);
    return strCipher;
}

string Decrypt(const string &strCipher, const string &strKey/* = "" */)
{
    std::string strText;
    int nLen = 0;
    CZYAes aes;

    if (!strKey.empty())
    {
        aes.SetKey(strKey, "");
    }
    strText = aes.Decrypt(strCipher);
    return strText;
}

实现文件

//*****************************************************************************
//@FileName    : zyaes256.h : the c interface of class zyaes
//@Version    : v1.0.0
//@Author    : xiaoc
//@Date        : 2015/03/13
//*****************************************************************************
#ifndef _ZYAES256_H_
#define _ZYAES256_H_
#include <string>

//*****************************************************************************
//@strText    : 需要加密的数据
//@strKey    : 加密用的密钥
//@return      : 返回加密之后的数据
//*****************************************************************************
std::string Encrypt(const std::string &strText, const std::string &strKey = "");

//*****************************************************************************
//@strText    : 需要解密的数据
//@strKey    : 解密用的密钥
//@return      : 返回解密之后的数据
//*****************************************************************************
std::string Decrypt(const std::string &strCipher, const std::string &strKey = "");
#endif // _ZYAES256_H_

头文件

此次修改主要是上一个版本中没有考虑到加密数据在网络中的传输问题,因为加密数据不再是简单的ASCII字符,所以不能存在char数组中,上一版本中就因为这个问题导致了数据的丢失,因为加密数据中的0导致字符串被截断了。

因此现在的做法是,先对加密数据进行转换,转换为16进制。然后传输,解密端做相反处理即可。

其中有个疑问是,cryptopp加密库将加密数据存在string中,但是string为什么能够存储非ASCII字符呢?

时间: 2024-11-08 18:25:37

使用Crypto++库的CBC模式实现加密(二)的相关文章

使用Crypto++库的CBC模式实现加密

1 //***************************************************************************** 2 //@File Name : scsaes.h: the interface of crypto++ library 3 //@Version : V1.0.0 4 //@Author : xiaoc 5 //@Date : 2014/11/11 6 //**************************************

C语言实现CBC模式DES加密

#define SECTION_SIZE 8 //每段密文字节数,DES为8个字节64位 #define GET_BIT(x,y) (x |((BYTE)0xff <<9-y) | ((BYTE)0xff >>y)) //将X的第Y位保留,其余位置1 #define FORM_DWORD(p1,p2,p3,p4) ((((DWORD)p1) <<24) | (((DWORD)p2) <<16) | (((DWORD)p3) <<8) | ((DW

分组密码模式: CBC模式(密码分组链接模式)

CBC模式是将前一个密文分组与当前明文分组的内容混合起来进行加密的,这样就可以避免ECB模式的弱点. 在CBC模式中,首先将明文分组与前一个密文分组进行XOR运算,然后再进行加密,如下图所示: 如果将一个分组的加密过程分离出来,我们就可以很容易地比较出ECB模式和CBC模式的区别,ECB模式只进行了加密,而CBC模式则在加密之前进行了一次XOR,如下图所示: 当加密第一个明文分组时,由于不存在“前一个密文分组”,因此需要事先准备一个长度为一个分组的比特序列来代替“前一个密文分组”,这个比特序列称

解决AES算法CBC模式加密字符串后再解密出现乱码问题

问题 在使用 AES CBC 模式加密字符串后,再进行解密,解密得到的字符串出现乱码情况,通常都是前几十个字节乱码: 复现 因为是使用部门 cgi?AESEncryptUtil 库,找到问题后,在这里复现不太方便,这里使用 python 进行复现,可以方便复现. #!/usr/bin/env python #coding=utf-8 from Crypto.Cipher import AES ? PADDING = '\0' if __name__ == "__main__":? ?

python AES CBC模式加密

今天需要用到AES CBC模式加密,搜索了很久,终于加密成功,记录一下今天的理解. 首先要安装pycrypto库,不知道为什么在windows安装失败,在linux可以正常安装 http://tool.chacuo.net/cryptaes,https://tools.lami.la/jiami/aes,以下代码加密后结果与这两个网页加密后一样. 这里有几点要注意,key的长度要是16,24或32,text的长度要是16的倍数,不满足长度都会补全,补全的字符可以自己定义,比如key补全不一定要"

AES加密CBC模式 IOS - Java 互通共用

AES加密模式和填充方式 算法/模式/填充                16字节加密后数据长度        不满16字节加密后长度AES/CBC/NoPadding             16                          不支持AES/CBC/PKCS5Padding          32                          16AES/CBC/ISO10126Padding       32                          16AE

通过Jni实现AES的CBC模式加密解密

AES加密方式基本实现,出现一个问题就是代码的安全性.我们知道java层代码很容易被反编译,很有可能泄漏我们加密方式与密钥 内容,那我们该怎么办呢?我们可以使用c/c++实现加密,编译成So库的形式,可供java实现调用,这样就大大增强程序安全性,因为so反编译结果是 arm指令,没有java中smali那么易懂.完全使用c/c++实现可能会比较麻烦,其实我们也可以简化一部分,只将密钥使用jni实现,其它还是用java实现,这样会简单一些,下面是具体操作: (1)新建项目aes 在java类中添

C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式

============================================== des   cbc  加密 zeropadding填充方式 ============================================== //加密 cbc zeropadding 自己实现 std::string des_cbc_zero_encrypt(const std::string &clearText, const std::string &key) { static u

php AES cbc模式 pkcs7 128位加密解密(微信小程序)

PHP AES CBC模式PKCS7 128位加密 加密: $key = '1234567812345678'; $iv = '1234567890123456'; $message = '123456'; $blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $len = strlen($message); //取得字符串长度 $pad = $blocksize - ($len % $blocksiz