一、简介
Crypto++(也称为CryptoPP、libcrypto++ 或cryptlib)是一个免费的开源C++ 库,提供多种加密方案。由Wei Dai开发和维护,广泛应用于各种需要强密码安全性的应用中。该库提供了多种加密算法和协议的实现,包括:
对称加密算法:AES、DES、3DES、RC2、RC4、RC5、RC6、Blowfish、Twofish 等。
非对称加密算法:RSA、DSA、ElGamal、ECC(椭圆曲线加密)等。
哈希函数:SHA-1、SHA-2(SHA-224、SHA-256、SHA-384、SHA-512)、MD2、MD4、MD5、RIPEMD-160 等。
消息认证码(MAC):HMAC、CMAC等
数字签名算法:DSA、ECDSA、EdDSA等。
随机数生成器:各种伪随机数生成器和真随机数生成器。
加密协议:SSL/TLS、SRP(安全远程加密协议)等
Crypto++ 旨在提供高性能、高质量的加密算法实现,可以轻松集成到C++ 应用程序中。它是一个跨平台库,支持Windows、Linux 和macOS 等多种操作系统。
二、下载
加密++下载:
Crypto++ Library 8.9 | 用于加密方案的免费C++ 类库
或标签· weidai11/cryptopp · GitHub
cryptopp-pem 下载:
PEM Pack – Crypto++ Wiki,滚动到页面底部即可下载
PEM 包是消息加密的部分实现,允许您读取和写入PEM 编码的密钥和参数,包括加密的私钥。该软件包还提供对RSA、DSA、EC、ECDSA 密钥和Diffie-Hellman 参数的支持。该软件包包括五个额外的源文件、一个使用OpenSSL 创建测试密钥的脚本、一个用于测试读写密钥的C++ 程序以及一个用于验证Crypto++ 编写的密钥的脚本。
最终下载的文件为:
cryptopp-CRYPTOPP_8_7_0.zip
cryptopp-pem-master.zip
三、编译静态库
1.解压cryptopp-CRYPTOPP_8_7_0.zip。
解压cryptopp-pem-master.zip 并将所有内容复制到cryptopp-CRYPTOPP_8_7_0。
2.在VS中打开cryptest.sln项目
3. 将pem包添加到子项目cryptlib中。
选择cryptlib,右键单击“头文件”,然后选择“添加”>“现有项”。
聚乙二醇
pem_common.h
右键单击“源文件”选择“添加”“现有项目”。
pem_common.cpp
pem_read.cpp
pem_write.cpp
4.修改属性页-配置属性-C/C++-代码生成-运行时库。调试模式选择“多线程调试DLL(/MDd)”或“多线程调试(/MTd)”,并选择“多线程DLL(/MD)”或“多线程(/MT)”为了释放。模式。
5、编译生成,右键子项目cryptlib,点击Generate。
6. 发布为SDK
创建一个文件夹cryptopp870,在其中创建一个include文件夹(要保存.h文件的文件夹),并创建一个lib文件(要保存.lib文件的文件夹)。
复制并包含cryptopp-CRYPTOPP_8_7_0 中的所有头文件。
将xxx/cryptopp-CRYPTOPP_8_7_0\\x64\\Output 中的Debug 和Release 文件夹复制到lib。
运行时说明:
在Visual C++ 中,运行时库有四个主要选项,它们在编译和链接时使用不同的设置。这些选项主要影响程序的内存管理、异常处理和调试支持。以下是四个选项之间的差异:
多线程(/MT)
描述:使用静态链接的多线程运行时库。
特征:
所有运行时代码都静态链接到可执行文件中,因此程序在运行时不需要额外的DLL 支持。
可执行文件包含运行时库的所有代码,因此它很大。
它适合发布版本,因为它不需要依赖外部DLL。
适用场景:不需要依赖外部DLL的独立应用程序。
多线程调试(/MTd)
描述:使用静态链接的多线程调试运行时库。
特征:
与/MT 类似,但包含适合调试版本的调试信息。
可执行文件包含运行时库的所有代码和调试信息,因此较大。
适合调试版本,因为有更详细的调试信息可用。
适用场景:需要详细调试信息的调试版本。
多线程DLL (/MD)
描述:使用动态链接的多线程运行时库。
特征:
该程序在运行时必须依赖于msvcrt.dll(Microsoft Visual C++运行时库DLL)。
可执行文件很小,因为它只包含程序本身的代码,运行时库代码在msvcrt.dll中。
它适合发布版本,因为它允许较小的可执行文件大小。
适用场景:需要减小可执行文件大小的Release版本。
多线程调试DLL (/MDd)
描述:使用动态链接的多线程调试运行时库。
特征:
与/MD 类似,但包含适合调试版本的调试信息。
该程序在运行时必须依赖于msvcrtd.dll(Microsoft Visual C++调试运行时库DLL)。
适合调试版本,因为有更详细的调试信息可用。
适用场景:需要详细调试信息的调试版本。
概括:
/MT 和/MTd 使用静态链接,适合不需要依赖外部DLL 的独立应用程序。
/MD 和/MDd 使用动态链接,适合需要减小可执行文件大小或需要依赖外部DLL 的应用程序。
调试版本通常使用/MTd 或/MDd,因为它们包含对调试有用的调试信息。
选择运行时选项时,您应该根据您的特定需求和项目配置来决定使用哪个选项。确保所有相关的库和模块使用相同的运行时选项以避免链接错误。
例如,如果您有一个使用/MD 选项编译的静态库mylib.lib,则任何使用mylib.lib 的可执行文件或DLL 也必须使用/MD 选项进行编译。
四、使用示例
VS配置:
新建测试项目并添加依赖库
属性页-配置属性-C/C++-常规-附加包含目录,输入头文件路径E:\\3rdparty\\dist\\cryptopp870\\include
属性页-配置属性-链接器-常规-附加库目录,输入lib文件路径E:\\3rdparty\\dist\\cryptopp870\\lib\\Debug
属性页——“配置属性”——“链接器”——“输入”——“添加附加依赖项,cryptlib.lib”
QT配置:
配置(调试,调试|发布){
QMAKE_CXXFLAGS_DEBUG +=/MTd # 或/MDd
}
CONFIG(发布,调试|发布){
QMAKE_CXXFLAGS_RELEASE +=/MT # 或/MD
}
win32:CONFIG(发布,调试|发布): LIBS +=-L$$PWD/cryptopp870/lib/Release/-lcryptlib
else:win32:CONFIG(调试、调试|发布): LIBS +=-L$$PWD/cryptopp870/lib/Debug/-lcryptlib
INCLUDEPATH +=$$PWD/cryptopp870/include
DEPENDPATH +=$$PWD/cryptopp870/include
win32-g++:CONFIG(发布、调试|发布): PRE_TARGETDEPS +=$$PWD/cryptopp870/lib/Release/libcryptlib.a
else:win32-g++:CONFIG(调试、调试|发布): PRE_TARGETDEPS +=$$PWD/cryptopp870/lib/Debug/libcryptlib.a
else:win32:win32-g++:CONFIG(发布、调试|发布): PRE_TARGETDEPS +=$$PWD/cryptopp870/lib/Release/cryptlib.lib
else:win32:win32-g++:CONFIG(调试,调试|发布): PRE_TARGETDEPS +=$$PWD/cryptopp870/lib/Debug/cryptlib.lib
4.1、RSA非对称加密
#包括iostream
#包含字符串
#includesa.h
#includeosrng.h
#includebase64.h
#include 文件.h
#include pem.h
使用命名空间标准。
使用命名空间CryptoPP。
类RSAKeyManager {
公共:
RSAKeyManager() {}
无效生成密钥(int keySize=2048){
AutoSeedRandomPool rng;
privateKey.GenerateRandomWithKeySize(rng, keySize);
公钥=RSA:PublicKey(私钥);
}
std:string GetPrivateKeyPEM() const {
std: 字符串私钥PEM;
StringSink privateKeySink(privateKeyPEM);
PEM_Save(privateKeySink, privateKey);
返回privateKeyPEM。
}
std:string GetPublicKeyPEM() const {
std: 字符串公钥PEM;
StringSink publicKeySink(publicKeyPEM);
PEM_Save(publicKeySink, publicKey);
返回publicKeyPEM。
}
void SavePrivateKey(const char* 文件名) const {
FileSink 文件(文件名);
PEM_Save(文件, 私钥);
}
void SavePublicKey(const char* 文件名) const {
FileSink 文件(文件名);
PEM_Save(文件, 公钥);
}
void LoadPrivateKey(const char* 文件名) {
FileSource 文件(文件名,true);
PEM_Load(文件, 私钥);
}
void LoadPublicKey(const char* 文件名) {
FileSource 文件(文件名,true);
PEM_Load(文件, 公钥);
}
void LoadPrivateKeyFromString(const std:string privateKeyPEM) {
StringSource 源(privateKeyPEM, true);
PEM_Load(源,私钥);
}
void LoadPublicKeyFromString(const std:string publicKeyPEM) {
StringSource 源(publicKeyPEM, true);
PEM_Load(源,公钥);
}
std:string 加密(const std:string message) const {
AutoSeedRandomPool rng;
std: 字符串已加密。
RSAES_OAEP_SHA_Encryptor 加密器(公钥);
字符串源(消息,true,
新的PK_EncryptorFilter(rng, 加密,
新的StringSink (加密)
)
);
它将被加密返回。
}
std:string 解密(const std:string 加密) const {
AutoSeedRandomPool rng;
std: 字符串已解密。
RSAES_OAEP_SHA_Decryptor 解密器(privateKey);
StringSource(加密,true,
新的PK_DecryptorFilter(rng, 解密器,
新的StringSink (已解密)
)
);
解密并返回。
}
私人:
RSA:PrivateKey私钥;
RSA:PublicKey 公钥;
};
int main() {
尝试{
RSAKeyManager 密钥管理器;
//生成密钥对
keyManager.GenerateKeys();
//将私钥和公钥转换为PEM 格式
std:string privateKeyPEM=keyManager.GetPrivateKeyPEM();
std:cout \’RSA 私钥:\’ std:endl;
std:cout privateKeyPEM std:endl;
std:string publicKeyPEM=keyManager.GetPublicKeyPEM();
std:cout \’RSA 公钥:\’ std:endl;
std:cout publicKeyPEM std:endl;
//从字符串加载密钥对
加载了RSAKeyManager 的KeyManager;
已加载KeyManager.LoadPrivateKeyFromString(privateKeyPEM);
LoadedKeyManager.LoadPublicKeyFromString(publicKeyPEM);
//加密
字符串消息=\’你好,世界!\’;
String Encrypt=已加载KeyManager.Encrypt(message);
//解密
字符串解密=加载的KeyManager.Decrypt(加密);
//输出结果
cout \’原始消息:\’消息endl;
cout \’加密消息:\’ 加密endl;
cout \’已解码的message:\’ 已解码的endl;
}
catch (const 异常e) {
cout \’Crypto++ 异常: \’ e.what() endl;
}
catch (const std: 异常e) {
cout \’标准异常: \’ e.what() endl;
}
抓住(.) {
cout \’未知异常\’ endl;
}
返回0。
}
4.2、RSA签名
生成密钥对、签名数据并验证签名
#包括iostream
#包含字符串
#includesa.h
#includeosrng.h
#includebase64.h
#include 文件.h
#include pem.h
#includesha.h
#include 十六进制.h
包含#pssr.h
使用命名空间标准。
使用命名空间CryptoPP。
无效生成密钥对(RSA:PrivateKey私钥,RSA:PublicKey公钥){
AutoSeedRandomPool rng;
privateKey.GenerateRandomWithKeySize(rng, 2048);
公钥=RSA:PublicKey(私钥);
}
bool SignMessage(const string message, const RSA:PrivateKey privateKey, 字符串签名) {
尝试
{
AutoSeedRandomPool rng;
RSASSPSS,SHA256: 签名者签名者(私钥);
字符串源(消息,true,
新的SignerFilter(rng, 签名者,
新StringSink(签名)
)
);
}
catch (const 异常e)
{
cout \’签署异常:\’ e.what() endl;
返回假。
}
返回真。
}
bool verifyMessage(const 字符串消息, const 字符串签名, const RSA:PublicKey 公钥) {
尝试{
RSASSPSS,SHA256: 验证者verifier(publicKey);
/* 解密用法和签名*/
StringSource ss(消息+ 签名, true,
新的SignatureVerificationFilter(验证者,
无效的,
签名验证过滤器:THROW_EXCEPTION | 签名验证过滤器:PUT_MESSAGE
)
);
}
catch (const 异常e) {
cout \’验证器异常: \’ e.what() endl;
返回假。
}
返回真。
}
结构许可证数据{
字符串消息=\’2024/6/19, 2024/7/19\’;
String签名; /* 数字签名,检查数据是否被修改*/
字符串公钥; /* 公钥*/
};
int main() {
尝试{
RSA:PrivateKey私钥;
RSA:PublicKey 公钥;
//生成密钥对
生成密钥对(p
rivateKey, publicKey);
// 要签名的消息
string message = \”Hello, World!\”;
// 签名消息
string signature;
bool b = SignMessage(message, privateKey, signature);
cout << \”signature:\” << b << endl << signature << endl;
// 验证签名
b= VerifyMessage(message, signature, publicKey);
if (b) {
cout << \”Signature is valid.\” << endl;
}
else {
cout << \”Signature is invalid.\” << endl;
}
}
catch (const Exception& e) {
cout << \”Crypto++ exception: \” << e.what() << endl;
}
catch (const std::exception& e) {
cout << \”Standard exception: \” << e.what() << endl;
}
catch (…) {
cout << \”Unknown exception\” << endl;
}
return 0;
}
4.3、 Base64 编码和解码
#include <iostream>
#include <string>
#include <rsa.h>
#include <osrng.h>
#include <base64.h>
#include <files.h>
#include <pem.h>
using namespace std;
using namespace CryptoPP;
class Base64 {
public:
static std::string encode(const std::string& data) {
std::string encoded;
CryptoPP::Base64Encoder encoder;
encoder.Attach(new CryptoPP::StringSink(encoded));
encoder.Put((const byte*)data.data(), data.size());
encoder.MessageEnd();
return encoded;
}
static std::string decode(const std::string& encoded) {
std::string decoded;
CryptoPP::Base64Decoder decoder;
decoder.Attach(new CryptoPP::StringSink(decoded));
decoder.Put((const byte*)encoded.data(), encoded.size());
decoder.MessageEnd();
return decoded;
}
};
int main()
{
try {
// 原始数据
std::string data = \”Hello, World!\”;
// Base64 编码
std::string encoded = Base64::encode(data);
std::cout << \”Encoded data: \” << encoded << std::endl;
// Base64 解码
std::string decoded = Base64::decode(encoded);
std::cout << \”Decoded data: \” << decoded << std::endl;
}
catch (const Exception& e) {
cout << \”Crypto++ exception: \” << e.what() << endl;
}
catch (const std::exception& e) {
cout << \”Standard exception: \” << e.what() << endl;
}
catch (…) {
cout << \”Unknown exception\” << endl;
}
return 0;
}
4.4、AES对称加密
#include <iostream>
#include <string>
#include <aes.h>
#include <modes.h>
#include <filters.h>
#include <hex.h>
#include <osrng.h>
using namespace std;
using namespace CryptoPP;
class AESCipher {
public:
AESCipher(const string& key, const string& iv) : key(key), iv(iv) {}
string Encrypt(const string& plainText) {
string cipherText;
try {
CBC_Mode<AES>::Encryption encryptor;
encryptor.SetKeyWithIV((byte*)key.data(), key.size(), (byte*)iv.data());
StringSource(plainText, true,
new StreamTransformationFilter(encryptor,
new StringSink(cipherText)
)
);
}
catch (const Exception& e) {
cerr << \”Encryption error: \” << e.what() << endl;
}
return cipherText;
}
string Decrypt(const string& cipherText) {
string plainText;
try {
CBC_Mode<AES>::Decryption decryptor;
decryptor.SetKeyWithIV((byte*)key.data(), key.size(), (byte*)iv.data());
StringSource(cipherText, true,
new StreamTransformationFilter(decryptor,
new StringSink(plainText)
)
);
}
catch (const Exception& e) {
cerr << \”Decryption error: \” << e.what() << endl;
}
return plainText;
}
private:
string key;
string iv;
};
int main() {
// 生成随机的密钥和初始化向量(IV)
AutoSeededRandomPool rng;
byte key[AES::DEFAULT_KEYLENGTH];
byte iv[AES::BLOCKSIZE];
rng.GenerateBlock(key, sizeof(key));
rng.GenerateBlock(iv, sizeof(iv));
string keyStr(reinterpret_cast<char*>(key), sizeof(key));
string ivStr(reinterpret_cast<char*>(iv), sizeof(iv));
AESCipher aes(keyStr, ivStr);
string plainText = \”Hello, World!\”;
string encryptedText = aes.Encrypt(plainText);
string decryptedText = aes.Decrypt(encryptedText);
cout << \”Original Text: \” << plainText << endl;
cout << \”Encrypted Text: \” << encryptedText << endl;
cout << \”Decrypted Text: \” << decryptedText << endl;
return 0;
}
#以上关于Crypto++ 入门的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92217.html