系列文章目录
1.(全网最详细攻略)【Crypto++】在Visual studio2022中运行Cryptopp
文章目录
- 系列文章目录
- 前言
- 一、RSA加密过程、步骤
- 可学习的网址
- 二、代码部分
- 1.visual studio编程注意
- 一个标准案例提供给大家
- 2.RSA密钥生成
- 思考:
- 3.关于RSA的五个基本函数
- 完整代码如下:
- VS 使用技巧总结
- 1. VS修改每次新建源文件或头文件时将自动添加写好的注释内容.
- 2. 一次性修改所有相关命令
前言
crypto++是一个开源密码学函数库,里面含有很多加密函数的库供大家引用,在官网中也能看到许多代码示范样例。
本文将记录如何使用开发环境:visual studio,引用crypto++的库编写RSA加密的代码。
一、RSA加密过程、步骤
RSA的安全性依赖于大数分解,由于进行的都是大数计算,使得RSA最快的情况也比DES慢上好几倍,无论是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。多用于数字签名。下面是数字签名的步骤:
- 待发送消息(message)利用Hash函数,生成信息的摘要
- 私钥加密摘要,生成”数字签名”(signature)
- 发送message+signature
- 公钥解密签名
- message重新生成摘要,与发送过来的摘要进行比较
公钥和私钥:公钥和私钥是成对的,它们互相解密。
- 加密:公钥加密,私钥解密。
- 数字签名:私钥数字签名,公钥验证。
可学习的网址
RSA原理:这个网址讲得详细,可参考学习
crypto++官网中RSA的相关代码:RSA Cryptography
这个博主写的代码很详细:RSA封装代码学习
二、代码部分
1.visual studio编程注意
在visual studio中,仅支持一个main函数,所以使用多个完整的cpp结构编写源代码将无法正确运行。
正确做法:封装。编写一个主函数main。cpp,使用多个头文件xxx.h编写头文件和函数声明部分,使用多个xxx.cpp编写函数定义部分,在main.cpp中集中调用。一个标准案例提供给大家
如何在VisualStdio中运行一个包含多个源文件的程序
2.RSA密钥生成
void GenerateKeys(AutoSeededRandomPool rng, InvertibleRSAFunction parameters) {
parameters.GenerateRandomWithKeySize(rng, 1024);
RSA::PrivateKey privateKey(parameters);
RSA::PublicKey publicKey(parameters);
}
思考:
此处使用
void
作为函数返回值是不对的,因为我们要产生一对公私钥密钥对。所以我们应该使用什么来接收结果(公钥,私钥)?
需要构造结构体!
struct key
{
RSA::PrivateKey private_key;
RSA::PublicKey public_key;
};
MyRSA.h
struct key
{
RSA::PrivateKey private_key;
RSA::PublicKey public_key;
};
key generate_key(unsigned int key_size = 2048);
RSA.cpp
#include "MyRSA.h"
/**
* \brief 生成密钥对
* \param key_size
* \return
*/
key generate_key(const unsigned int key_size) //钥匙的长度,通常是2048以上,越大相对越安全,但相对的运算越久
{
AutoSeededRandomPool rng; //伪随机数
InvertibleRSAFunction params;
params.GenerateRandomWithKeySize(rng, key_size);
key keys;
keys.private_key = params;
keys.public_key = params; //根据这个参数产生配对的公钥、密钥并返回这个集合
return keys;
}
3.关于RSA的五个基本函数
- 生成密钥对
- 加密
- 解密
- 私钥签名
- 公钥验证签名
完整代码如下:
initializeCrypto.h
/*
*
* Created on: 2023-8-28
* Author: Chen Jingyan
*/
#include "cryptlib.h"
using namespace CryptoPP;
MyRSA.h
#ifndef CRYPTO_RSA_H
#define CRYPTO_RSA_H
#include"initializeCrypto.h"
#include "pssr.h"
#include "rsa.h"
#include "osrng.h"
struct key
{
RSA::PrivateKey private_key;
RSA::PublicKey public_key;
};
key generate_key(unsigned int key_size = 2048);
bool rsa_encrypt(const std::string& plain, RSA::PublicKey& public_key, std::string& cipher);
bool rsa_decrypt(const std::string& cipher, RSA::PrivateKey& private_key, std::string& recovered);
bool rsa_signature(const std::string& plain, RSA::PrivateKey& private_key, std::string& signature);
bool rsa_verify(const std::string& cipher_sign, RSA::PublicKey& public_key, std::string& recovered);
#endif
RSA.CPP
#include "MyRSA.h"
/**
* \brief 生成密钥对
* \param key_size
* \return
*/
key generate_key(const unsigned int key_size) //钥匙的长度,通常是2048以上,越大相对越安全,但相对的运算越久
{
AutoSeededRandomPool rng; //伪随机数
InvertibleRSAFunction params;
params.GenerateRandomWithKeySize(rng, key_size);
key keys;
keys.private_key = params;
keys.public_key = params; //根据这个参数产生配对的公钥、密钥并返回这个集合
return keys;
}
/**
* \brief RSA加密(OAEP方案) 最佳非对称加密填充(OAEP)
* \param plain 待加密原文
* \param public_key 公钥
* \param cipher 密文
* \return 加密成功或失败
*/
bool rsa_encrypt(const std::string& plain, RSA::PublicKey& public_key, std::string& cipher)
{
try
{
AutoSeededRandomPool rng;
const RSAES_OAEP_SHA_Encryptor encrypt(public_key);
StringSource ss_1(plain, true, new PK_EncryptorFilter(rng, encrypt, new StringSink(cipher)));
}
catch (...)
{
return false;
}
return true;
}
/**
* \brief RSA解密(OAEP方案)
* \param cipher 密文
* \param private_key 密钥
* \param recovered 恢复的原文
* \return 恢复成功或失败
*/
bool rsa_decrypt(const std::string& cipher, RSA::PrivateKey& private_key, std::string& recovered)
{
try
{
AutoSeededRandomPool rng;
const RSAES_OAEP_SHA_Decryptor decrypt(private_key);
StringSource ss_2(cipher, true, new PK_DecryptorFilter(rng, decrypt, new StringSink(recovered)));
}
catch (...)
{
return false;
}
return true;
}
/**
* \brief:签名
* \param plain
* \param private_key
* \param signature
* \return
*/
bool rsa_signature(const std::string& plain, RSA::PrivateKey& private_key, std::string& signature)
{
try
{
AutoSeededRandomPool rng;
const RSASS< PSS, SHA256>::Signer signer(private_key);
StringSource ss_1(plain, true, new SignerFilter(rng, signer, new StringSink(signature)));
}
catch (...)
{
return false;
}
return true;
}
/**
* \brief:公钥验证签名
* \param cipher_sign
* \param public_key
* \param recovered
* \return true/faluse
*/
bool rsa_verify(const std::string& cipher_sign, RSA::PublicKey& public_key, std::string& recovered)
{
try
{
const RSASS< PSS, SHA256>::Verifier verifier(public_key);
StringSource ss_2(cipher_sign, true,
new SignatureVerificationFilter(verifier,
new StringSink(recovered), SignatureVerificationFilter::THROW_EXCEPTION | SignatureVerificationFilter::PUT_MESSAGE));
}
catch (...)
{
return false;
}
return true;
}
main.cpp
#include "timeSpan.h"
#include"MyRsa.h"
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
/*RSA加密*/
key keys = generate_key();
const string plain = "HelloWorld";
string cipher, recovered;
if (rsa_encrypt(plain, keys.public_key, cipher))
{
if (rsa_decrypt(cipher, keys.private_key, recovered))
{
cout << "Cipher: " << endl;
for (const auto& x : cipher)
{
cout
<< setfill('0')
<< setw(2)
<< setiosflags(ios::uppercase)
<< hex << static_cast<unsigned int>(static_cast<unsigned char>(x))
<< " ";
}
cout << "Recovered message: " << recovered << endl;
}
}
return 0;
}
VS 使用技巧总结
1. VS修改每次新建源文件或头文件时将自动添加写好的注释内容.
步骤:
- 根据下面地址找到文件
newc++file.cpp
:
D:\visual studio\Common7\IDE\VC\VCProjectItems\newc++file.cpp - 将其复制到桌面,然后用记事本方式打开;
- 修改注释内容,下面给一个例子:
/*
* file name:
*
* Created on: 2023--
* Author: 宇宙修理员
*/
- 保存后,将桌面文件复制回去步骤1的地址中,将原来文件覆盖。
2. 一次性修改所有相关命令
- 选定要修改的命令,ctrl+H,出现下面这个搜索框
- 输入空格,点击“全部替换”图标。