Crypto++的使用
Crypto++是C++平台的加密库。
本文使用的是Crypto++® Library 8.7.0版本,Release Date: 2022-08-07。
安装过程就不说了,不安装的话会在#include
的时候找不到库。
ECDSA
对ECDSA进行了尝试。
生成密钥对
cpp
#include <iostream>
#include <cryptopp/eccrypto.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>
#include <oids.h>
void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey);
void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey);
int main() {
CryptoPP::AutoSeededRandomPool rng;
// 生成ECDSA密钥对
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Initialize(rng, CryptoPP::ASN1::secp256r1());
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);
// 输出密钥对
printPrivateKey(privateKey);
printPublicKey(publicKey);
return 0;
}
void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey) {
std::string privateKeyStr;
CryptoPP::HexEncoder privateKeyEncoder(new CryptoPP::StringSink(privateKeyStr));
privateKey.Save(privateKeyEncoder);
privateKeyEncoder.MessageEnd();
std::cout << "Private Key (hex): 0x" << privateKeyStr << std::endl;
}
void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey) {
std::string publicKeyStr;
CryptoPP::HexEncoder publicKeyEncoder(new CryptoPP::StringSink(publicKeyStr));
publicKey.Save(publicKeyEncoder);
publicKeyEncoder.MessageEnd();
std::cout << "Public Key (hex): 0x" << publicKeyStr << std::endl;
}
程序输出:
bash
Private Key (hex): 0x3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420B7A27F63D22AA537DA9B277FB41C28E1986BCBD09AF449394CD9D942824F06C6
Public Key (hex): 0x3059301306072A8648CE3D020106082A8648CE3D030107034200044C2DEFDDC23725CA4A55722F13BD71DC00310426901E0527B5494A1DFAB18486FF35675D93EDB2166F020AE84524E4CDC72446C80E52B29D47E5D0B8D5C09290
Process finished with exit code 0
签名
cpp
#include <iostream>
#include <cryptopp/eccrypto.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>
#include <oids.h>
#include <cryptopp/cryptlib.h>
void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey);
void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey);
std::string fromHex(const std::string &from);
std::string toHex(const std::string &from);
std::string
sign(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message);
std::string
signToHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message);
bool verifyFromHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey,
const std::string &signatureHex, const std::string &message);
bool verify(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &signature,
const std::string &message);
int main() {
CryptoPP::AutoSeededRandomPool rng;
// 生成ECDSA密钥对
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Initialize(rng, CryptoPP::ASN1::secp256r1());
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);
// 输出密钥对
printPrivateKey(privateKey);
printPublicKey(publicKey);
/// ECDSA
// 签名消息
std::string message = "Hello, Crypto++!";
std::string signature = sign(privateKey, message);
std::string signatureHex = signToHex(privateKey, message);
// 验证签名
bool valid = verifyFromHex(publicKey, signatureHex, message) && verify(publicKey, signature, message);
// 输出签名和验证结果
std::cout << "Message: " << message << std::endl;
std::cout << "Signature (hex): 0x" << signatureHex << std::endl;
std::cout << "Signature Valid: " << (valid ? "true" : "false") << std::endl;
return 0;
}
void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey) {
std::string privateKeyStr;
CryptoPP::HexEncoder privateKeyEncoder(new CryptoPP::StringSink(privateKeyStr));
privateKey.Save(privateKeyEncoder);
privateKeyEncoder.MessageEnd();
std::cout << "Private Key (hex): 0x" << privateKeyStr << std::endl;
}
void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey) {
std::string publicKeyStr;
CryptoPP::HexEncoder publicKeyEncoder(new CryptoPP::StringSink(publicKeyStr));
publicKey.Save(publicKeyEncoder);
publicKeyEncoder.MessageEnd();
std::cout << "Public Key (hex): 0x" << publicKeyStr << std::endl;
}
std::string
sign(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message) {
CryptoPP::AutoSeededRandomPool rng;
std::string signature;
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer signer(privateKey);
CryptoPP::StringSource signerStringSource(message, true, new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::StringSink(
signature)));
return signature;
}
std::string
signToHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message) {
CryptoPP::AutoSeededRandomPool rng;
std::string signature;
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer signer(privateKey);
CryptoPP::StringSource signerStringSource(message, true, new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::StringSink(
signature)));
return toHex(signature);
}
bool verify(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &signature,
const std::string &message) {
bool valid = false;
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier verifier(publicKey);
CryptoPP::StringSource verifierStringSource(signature + message, true,
new CryptoPP::SignatureVerificationFilter(verifier,
new CryptoPP::ArraySink(
reinterpret_cast<CryptoPP::byte *>(&valid),
sizeof(bool))));
return valid;
}
bool verifyFromHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey,
const std::string &signatureHex, const std::string &message) {
//TODO:把16进制字符串转化为签名的时候出错
std::string signature = fromHex(signatureHex);
return verify(publicKey, signature, message);
}
std::string fromHex(const std::string &from) {
std::string to;
CryptoPP::StringSource hexStringSource(from, true,
new CryptoPP::HexDecoder(new CryptoPP::StringSink(to)));
return to;
}
std::string toHex(const std::string &from) {
std::string to;
CryptoPP::StringSource hexStringSource(from, true,
new CryptoPP::HexEncoder(new CryptoPP::StringSink(to)));
return to;
}
程序输出:
bash
Private Key (hex): 0x3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420DF7A3D580D8F2676D852E5930F50468575E9B2526EA14D9A9F06971A8CC10553
Public Key (hex): 0x3059301306072A8648CE3D020106082A8648CE3D03010703420004BFBAD0BF5AEE8841F7CA233C0932CD4A48DF5CC8D591A5DA4EE9BAEB585D87D913179A5724FA1DB04FEB2FFB8083D4676D60EC4C0526026C33DABBFD5ECBD6EA
Message: Hello, Crypto++!
Signature (hex): 0xB8B36223EF4F212ED8B16F4844A7FC3C8046096E2B77D726A0770D8C917CA0943B9CAA2BEBCF6023A77A6A21E4C92F58D71E5A6FF00557C590EA0C458ECDEEBA
Signature Valid: true
Process finished with exit code 0
ECC 与 SHA256
代码是在上面ECDSA的基础上加的,并未删去ECDSA的代码。
cpp
#include <iostream>
#include <cryptopp/eccrypto.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>
#include <oids.h>
#include <cryptopp/cryptlib.h>
void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey);
void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey);
std::string fromHex(const std::string &from);
std::string toHex(const std::string &from);
std::string
sign(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message);
std::string
signToHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message);
bool verifyFromHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey,
const std::string &signatureHex, const std::string &message);
bool verify(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &signature,
const std::string &message);
std::string
encrypt(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &message);
std::string
encryptToHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &message);
std::string
decrypt(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &ciphertext);
std::string
decryptFromHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey,
const std::string &ciphertextHex);
std::string sha256Hex(const std::string &data);
int main() {
CryptoPP::AutoSeededRandomPool rng;
// 生成ECDSA密钥对
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Initialize(rng, CryptoPP::ASN1::secp256r1());
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);
// 输出密钥对
printPrivateKey(privateKey);
printPublicKey(publicKey);
/// ECDSA
// 签名消息
std::string message = "Hello, Crypto++!";
std::string signature = sign(privateKey, message);
std::string signatureHex = signToHex(privateKey, message);
// 验证签名
bool valid = verifyFromHex(publicKey, signatureHex, message) && verify(publicKey, signature, message);
// 输出签名和验证结果
std::cout << "Message: " << message << std::endl;
std::cout << "Signature (hex): 0x" << signatureHex << std::endl;
std::cout << "Signature Valid: " << (valid ? "true" : "false") << std::endl;
/// ECC
// 加密
std::string ciphertext = encrypt(publicKey, message);
std::string ciphertextHex = encryptToHex(publicKey, message);
// 解密
std::string decryptedMessage = decrypt(privateKey, ciphertext);
std::string decryptedMessageFromHex = decryptFromHex(privateKey, ciphertextHex);
// 输出结果
std::cout << "Original Message: " << message << std::endl;
std::cout << "Encrypted Message (hex): 0x" << ciphertextHex << std::endl;
std::cout << "Decrypted Message: " << decryptedMessage << std::endl;
std::cout << "Decrypted Hex Message: " << decryptedMessageFromHex << std::endl;
/// SHA256
std::string hash = sha256Hex(message);
std::cout << "SHA256 hash: " << hash << std::endl;
return 0;
}
void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey) {
std::string privateKeyStr;
CryptoPP::HexEncoder privateKeyEncoder(new CryptoPP::StringSink(privateKeyStr));
privateKey.Save(privateKeyEncoder);
privateKeyEncoder.MessageEnd();
std::cout << "Private Key (hex): 0x" << privateKeyStr << std::endl;
}
void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey) {
std::string publicKeyStr;
CryptoPP::HexEncoder publicKeyEncoder(new CryptoPP::StringSink(publicKeyStr));
publicKey.Save(publicKeyEncoder);
publicKeyEncoder.MessageEnd();
std::cout << "Public Key (hex): 0x" << publicKeyStr << std::endl;
}
std::string fromHex(const std::string &from) {
std::string to;
CryptoPP::StringSource hexStringSource(from, true,
new CryptoPP::HexDecoder(new CryptoPP::StringSink(to)));
return to;
}
std::string toHex(const std::string &from) {
std::string to;
CryptoPP::StringSource hexStringSource(from, true,
new CryptoPP::HexEncoder(new CryptoPP::StringSink(to)));
return to;
}
std::string
sign(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message) {
CryptoPP::AutoSeededRandomPool rng;
std::string signature;
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer signer(privateKey);
CryptoPP::StringSource signerStringSource(message, true, new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::StringSink(
signature)));
return signature;
}
std::string
signToHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &message) {
CryptoPP::AutoSeededRandomPool rng;
std::string signature;
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer signer(privateKey);
CryptoPP::StringSource signerStringSource(message, true, new CryptoPP::SignerFilter(rng, signer,
new CryptoPP::StringSink(
signature)));
return toHex(signature);
}
bool verify(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &signature,
const std::string &message) {
bool valid = false;
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier verifier(publicKey);
CryptoPP::StringSource verifierStringSource(signature + message, true,
new CryptoPP::SignatureVerificationFilter(verifier,
new CryptoPP::ArraySink(
reinterpret_cast<CryptoPP::byte *>(&valid),
sizeof(bool))));
return valid;
}
bool verifyFromHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey,
const std::string &signatureHex, const std::string &message) {
//TODO:把16进制字符串转化为签名的时候出错
std::string signature = fromHex(signatureHex);
return verify(publicKey, signature, message);
}
std::string
encrypt(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &message) {
CryptoPP::AutoSeededRandomPool rng;
std::string ciphertext;
CryptoPP::ECIES<CryptoPP::ECP>::Encryptor encryptor(publicKey);
CryptoPP::StringSource encryptorStringSource(message, true,
new CryptoPP::PK_EncryptorFilter(rng, encryptor,
new CryptoPP::StringSink(ciphertext)
)
);
return ciphertext;
}
std::string
encryptToHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey, const std::string &message) {
std::string ciphertext = encrypt(publicKey, message);
std::string ciphertextHex = toHex(ciphertext);
return ciphertextHex;
}
std::string
decrypt(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey, const std::string &ciphertext) {
CryptoPP::AutoSeededRandomPool rng;
std::string decryptedMessage;
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor decryptor(privateKey);
CryptoPP::StringSource decryptorStringSource(ciphertext, true,
new CryptoPP::PK_DecryptorFilter(rng, decryptor,
new CryptoPP::StringSink(
decryptedMessage)
)
);
return decryptedMessage;
}
std::string
decryptFromHex(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey,
const std::string &ciphertextHex) {
CryptoPP::AutoSeededRandomPool rng;
std::string ciphertext = fromHex(ciphertextHex);
std::string decryptedMessage;
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor decryptor(privateKey);
CryptoPP::StringSource decryptorStringSource(ciphertext, true,
new CryptoPP::PK_DecryptorFilter(rng, decryptor,
new CryptoPP::StringSink(
decryptedMessage)
)
);
return decryptedMessage;
}
std::string sha256Hex(const std::string &data) {
std::string hash;
CryptoPP::SHA256 sha256;
CryptoPP::StringSource source(data, true, new CryptoPP::HashFilter(sha256, new CryptoPP::HexEncoder(
new CryptoPP::StringSink(hash))));
return hash;
}
程序输出:
bash
Private Key (hex): 0x3041020100301306072A8648CE3D020106082A8648CE3D03010704273025020101042013EF286A25DA691FA334778E57854A3B3B5433AA59C1A50A079CCAE2C29E3E7B
Public Key (hex): 0x3059301306072A8648CE3D020106082A8648CE3D030107034200044A728F720A1238318414EFB63A7EC5405333E19918E45BC36C307AC236AC75E45E5B49FDD6DE1C42AA5D3E006CFC9BC11DA25F6FA018EC6A7DABEA348478140C
Message: Hello, Crypto++!
Signature (hex): 0xE69EFC191C9BD475611A3F04BCF26EF948DDB309EFCEEF80474A139546CA8450F58F222CFC6DAD16CA2B8567264D9684DFEB3D7C25660C7628A26ED376F08C2A
Signature Valid: true
Original Message: Hello, Crypto++!
Encrypted Message (hex): 0x04246E7A2B16DF57A93FFFEAAB4E04DC121532B88DFB09D36DAE3B1EEF3D9239D67ECEC3514778A83FB71CA66808AE94BE6CEB29E8BE8B099630FD80040B4283B8CDE2604C568C1BEFF186469CD44C25E01BFF875A502824DCDC437F1234AA20854C949928
Decrypted Message: Hello, Crypto++!
Decrypted Hex Message: Hello, Crypto++!
SHA256 hash: 9009F952CE7B1D25F58C83F59F96FE23C93B57B206EDB664F9162B47AC177AED
Process finished with exit code 0