【crypto++使用】使用crypto++库函数运行RSA非对称加密

系列文章目录

1.(全网最详细攻略)【Crypto++】在Visual studio2022中运行Cryptopp



前言

crypto++是一个开源密码学函数库,里面含有很多加密函数的库供大家引用,在官网中也能看到许多代码示范样例。
本文将记录如何使用开发环境:visual studio,引用crypto++的库编写RSA加密的代码。


一、RSA加密过程、步骤

RSA的安全性依赖于大数分解,由于进行的都是大数计算,使得RSA最快的情况也比DES慢上好几倍,无论是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。多用于数字签名。下面是数字签名的步骤:

  • 待发送消息(message)利用Hash函数,生成信息的摘要
  • 私钥加密摘要,生成”数字签名”(signature)
  • 发送message+signature
  • 公钥解密签名
  • message重新生成摘要,与发送过来的摘要进行比较

公钥和私钥:公钥和私钥是成对的,它们互相解密。

  1. 加密:公钥加密,私钥解密。
  2. 数字签名:私钥数字签名,公钥验证。

可学习的网址

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修改每次新建源文件或头文件时将自动添加写好的注释内容.

步骤:

  1. 根据下面地址找到文件newc++file.cpp
    D:\visual studio\Common7\IDE\VC\VCProjectItems\newc++file.cpp
  2. 将其复制到桌面,然后用记事本方式打开;
  3. 修改注释内容,下面给一个例子:
/*
 *  file name:
 *
 *  Created on: 2023--
 *      Author: 宇宙修理员
 */
  1. 保存后,将桌面文件复制回去步骤1的地址中,将原来文件覆盖。

2. 一次性修改所有相关命令

  1. 选定要修改的命令,ctrl+H,出现下面这个搜索框
    在这里插入图片描述
  2. 输入空格,点击“全部替换”图标。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值