Crypto++ 入门(cryptocoin)

Crypto++ 入门一、简介
Crypto(也称为CryptoPP、libcrypto或cryptlib)是一个免费的开源C库,提供了多种加密方案。它由Wei Dai开发和维护,广

一、简介

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

(0)
CSDN的头像CSDN
上一篇 2024年6月25日
下一篇 2024年6月25日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注