使用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字符呢?