Crypto使用指南
发布时间:2024.04.30
Crypto++入门- 安装
Crypto++是一个C++编写的密码学类库。读过《过河卒》的朋友还记得作者的那个不愿意去微软工作的儿子吗,就是Crypto++的作者Wei Dai。
Crypto++是一个非常强大的密码学库,在密码学界很受欢迎,最初还是Rivest(RSA的R)门下的一个博士姐姐把这个库介绍给我的。虽然网络上可以找到很多密码学相关的代码和库,但是Crypto++有其明显的优点。主要是功能全,统一性好。例如椭圆曲线加密算法和AES在OpenSSL的crypto库中就还没最终完成,而在Crypto++中就支持的比较好。基本上密码学中需要的主要功能都可以在里面找得到。Crypto++是由标准的C++写成的,学习C++、密码学、网络安全都可以通过阅读Crypto++的源代码得到启发和提高。
Crypto++的安装
首先到www.cryptopp.com上下载最新版本的源代码,如果是windows版的,会得到一个VC的项目,直接用VC打开就可以编译了。这里建议大家使用最新版的C++编译器,因为诸如VC6的编译器是不支持C++的标准的,很多符合C++标准的代码不能编译通过。编译的时间比较长,完成后会生成cryptlib.lib这个库文件。可以将Crypto++源文件的目录命名为cryptopp,拷贝到编译器的include目录(例如:C:VS.NETVC7include),将cryptlib.lib文件拷贝到编译器的lib目录。这样我们只需要说明链接cryptlib.lib即可。例如在VC7中在项目->属性->链接器->命令行->附加选项中添加“cryptlib.lib”。
Hello World
现在写一个hello world程序看看能不能编译通过。
#include <iostream>
using namespace std;
#include <cryptopp/aes.h>
using namespace CryptoPP;
int main()
{
cout << "hello crypto++" << endl;
cout << "Aes block size is " << AES::BLOCKSIZE << endl;
return 0;
}
编译运行,一切OK,哈哈:D,可以用了。
lib和dll文件的区别和联系
.dll是在你的程序运行的时候才连接的文件,因此它是一种比较小的可执行文件格式,.dll还有其他的文件格式如.ocx等,所有的.dll文件都是可执行。
.lib是在你的程序编译连接的时候就连接的文件,因此你必须告知编译器连接的lib文件在那里。一般来说,与动态连接文件相对比,lib文件也被称为是静态连接库。当你把代码编译成这几种格式的文件时,在以后他们就不可能再被更改。如果你想使用lib文件,就必须:
1 包含一个对应的头文件告知编译器lib文件里面的具体内容
2 设置lib文件允许编译器去查找已经编译好的二进制代码
如果你想从你的代码分离一个dll文件出来代替静态连接库,仍然需要一个lib文件。这个lib文件将被连接到程序告诉操作系统在运行的时候你想用到什么dll文件,一般情况下,lib文件里有相应的dll文件的名字和一个指明dll输出函数入口的顺序表。如果不想用lib文件或者是没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress。事实上,我们可以在Visual C++ IDE中以二进制形式打开lib文件,大多情况下会看到ASCII码格式的C++函数或一些重载操作的函数名字。
一般我们最主要的关于lib文件的麻烦就是出现unresolved symble这类错误,这就是lib文件连接错误或者没有包含.c、.cpp文件到工程里,关键是如果在C++工程里用了C语言写的lib文件,就必需要这样包含:
extern "C"
{
#include "myheader.h"
}
这是因为C语言写的lib文件没有C++所必须的名字破坏,C函数不能被重载,因此连接器会出错
C语言中有一些函数不需要进行编译,有一些函数也可以在多个文件中使用。一般来说,这些函数都会执行一些标准任务,如数据库输入/输出操作或屏幕控制等。可以事先对这些函数进行编译,然后将它们放置在一些特殊的目标代码文件中,这些目标代码文件就称为库。库文件中的函数可以通过连接程序与应用程序进行连接。这样就不必在每次开发程序时都对这些通用的函数进行编译了。
不同类型的应用程序将会使用不同的函数库。例如:libdbm库中组包含了对数据库文件进行访问的dbm函数,需要对数据库进行操作的程序就会与该库进行连接。数学应用程序将使用数学库libm,X-Windows应用程序将使用Xlib库,libX11。另外,所有的程序都将使用标准的C函数库。libc,该库中包含了诸好内存管理或输入输出操作的基本函数,这些库都存放在/usr/lib这些系统公用的目录中,系统中的任何用户都可以利用这些库。当然用户也可以建立自己专用的库函数,供自己或其它指定的人员使用。
库可以有三种使用的形式:静态、共享和动态。静态库的代码在编译时就已连接到开发人员开发的应用程序中,而共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。动态库则是共享库的另一种变化形式。动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其它程序使用。由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。
Crypto++库在VS 2005中的使用——RSA加解密
一. 下载Crypto++ Library
Crypto++ Library的官方网:http://www.cryptopp.com/
二. 建立自己使用的Crypto++ Library
由于从官方网下载的Crypto++库是开源的,只有源文件和几个可以生成lib、dll的工程,以及一个使用的例子工程,因此希望生成自己建的工程能使用的SDK。
1. 编译链接生成cryptlib.lib
打开cryptest.sln,分别在Debug模式和Release模式下编译链接cryptlib工程,成功后会在cryptopp54Win32outputdebug和cryptopp54Win32output elease下生成cryptlib.lib文件。作者当时用的是Crypto++ 5.4版本。
Build时方法是,右击Solution Explorer中的cryptlib工程,单击build。第一次时它会报错说“d:cryptopp54dler32.cpp(3) : fatal error C1033: cannot open program database 'd:cryptopp54win32cryptlibdebugc80.idb'”,没关系,按这样再build一次,就可以build成功了。
2. 建立Crypto++ SDK
在C:Program Files中新建文件夹,取名“CryptoPP”,里面新建文件夹“include”、“lib”,在“lib”中新建文件夹“debug”、“release”。将Crypto++库中的所有头文件复制到“include”文件夹中,再将上面生成的两个cryptlib.lib分别复制到“debug”和“release”中。
三. RSA加解密
1.
在VS 2005中新建Win32 Console Application工程,建立空的工程。完成后新建文件main.cpp,里面源码如下:
#include "randpool.h"
#include "rsa.h"
#include "hex.h"
#include "files.h"
#include <iostream>
using namespace std;
using namespace CryptoPP;
#pragma comment(lib, "cryptlib.lib")
//------------------------
// 函数声明
//------------------------
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
string RSADecryptString(const char *privFilename, const char *ciphertext);
RandomPool & GlobalRNG();
//------------------------
// 主程序
//------------------------
void main()
{
char priKey[128] = {0};
char pubKey[128] = {0};
char seed[1024] = {0};
// 生成 RSA 密钥对
strcpy(priKey, "pri"); // 生成的私钥文件
strcpy(pubKey, "pub"); // 生成的公钥文件
strcpy(seed, "seed");
GenerateRSAKey(1024, priKey, pubKey, seed);
// RSA 加解密
char message[1024] = {0};
cout<<"Origin Text: "<<"Hello World!"<<endl<<endl;
strcpy(message, "Hello World!");
string encryptedText = RSAEncryptString(pubKey, seed, message); // RSA 加密
cout<<"Encrypted Text: "<<encryptedText<<endl<<endl;
string decryptedText = RSADecryptString(priKey, encryptedText.c_str()); // RSA 解密
cout<<"Decrypted Text: "<<decryptedText<<endl<<endl;
}
//------------------------
// 生成RSA密钥对
//------------------------
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
HexEncoder privFile(new FileSink(privFilename));
priv.DEREncode(privFile);
privFile.MessageEnd();
RSAES_OAEP_SHA_Encryptor pub(priv);
HexEncoder pubFile(new FileSink(pubFilename));
pub.DEREncode(pubFile);
pubFile.MessageEnd();
}
//------------------------
// RSA加密
//------------------------
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
{
FileSource pubFile(pubFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Encryptor pub(pubFile);
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
string result;
StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
return result;
}
//------------------------
// RSA解密
//------------------------
string RSADecryptString(const char *privFilename, const char *ciphertext)
{
FileSource privFile(privFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Decryptor priv(privFile);
string result;
StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
return result;
}
//------------------------
// 定义全局的随机数池
//------------------------
RandomPool & GlobalRNG()
{
static RandomPool randomPool;
return randomPool;
}
2. 设置工程属性
选择工程属性(Alt + F7):
(1)“Configuration Properties”→“C/C++” →“General”,右边的“Additional Include Directories”设置为上面建好的Crypto++ SDK的Include文件夹,“C:Program FilesCyptoPPinclude”;
(2) “Configuration Properties”→“Linker” →“General”,右边的“Additional Library Directories”设置为上面建好的Crypto++ SDK的LibDebug文件夹,“C:Program FilesCyptoPPlibdebug”(Release模式下对应着Release文件夹);
(3) “Configuration Properties”→“C/C++” →“Code Generation”,右边的“Runtime Library”设置为“Multi-threaded Debug (/MTd)”(Release模式下对应着“Multi-threaded (/MT)”)
3. 运行程序(Ctrl + F5)
正常运行的输出结果为:
Origin Text: Hello World!
Encrypted Text: 79C72A482482EF45111F961772456310792AB735ECF72329ECB26292D2B26374
824E0E35D24A63CB03B867DD2C70B001FD4B2B33FBC984BD229A5226F284B889901817976A680322
9E8351372C5E28E8BEBA2A94E7CF61A8A162F0BA2F3E0C35D26842D92EC4866D25E6BF878743E481
84D9F6FF9BA690F953568D017C02D540
Decrypted Text: Hello World!
如果上面的第(3)步没有设置则会出现以下链接错误:
cryptlib.lib(randpool.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) already defined in msvcprtd.lib(MSVCP80D.dll)
说在msvcprtd.lib和MSVCRTD.lib中已经定义过。
Crypto++使用经验总结
?Crypto++使用经验总结
Crypto++是一套关于应用密码学的类库,提供了散列(MD5、SHA)、数据加密(DES、AES)、数字签名(RSA、椭圆曲线签名算法ECDSA)等很多有用的算法,算法安全性已经通过 FIPS 140-2(http://csrc.nist.gov/cryptval/140-2.htm) 验证。
?下面是一些使用中的总结:
?一、将一个缓冲区编码
1.首先声明一个字符串来存放编码的结果
string str;
2.接着声明一个编码器( HexEncoder 可替换为 Base64Encoder 等)对象,并通过 StringSink 类关联两者
HexEncoder encoder(new StringSink(str));
3.将数据放入编码器中
byte buf[1024];
...
encoder.Put(buf, sizeof(buf));
SetDlgItemText(IDC_EDIT_TEST, spk.data());
4.调用 MessageEnd 函数结束编码
encoder.MessageEnd();
?二、BufferedTransformation、BlockTransformation、StreamTransformation、HashTransformation
这几个类都是对输入的缓冲区进行某种运算后输出,但是有一些差别
1.BufferedTransformation:是对缓冲区进行某种变换,这种变换式可以还原的
2.BlockTransformation:基本与 BufferedTransformation 相同,不同之处在于它是以块为单位
3.StreamTransformation:与 BufferedTransformation 差不多相同,不同之处在于是以流式方式,如网络套结字
4.HashTransformation:是对缓冲区计算哈希值,这种变换是不可还原的
?三、Sink类及其派生类的作用
Sink 类及其派生类,以下简称 Sink 类,它们的作用是在真实的数据和缓冲区变换类之间起一个连接的作用, Sink 类由 BufferedTransformation 派生,但是不能产生任何输入输出,所有对它的操作都是对它所指向的数据的操作。每个 Sink 类必须与一个正式的数据关联起来。
1.ArraySink:操作字节数据
2.StringSink:操作字符串数据
3.ArrayXorSink:操作字节数据,但是会对缓冲区进行异或运算
4.FileSink:操作文件
?四、SecByteBlock 和 ByteQueue
两个类都描述了一个字节为单位的缓冲区,所不同的是 SecByteBlock 所分配的缓冲区时连续的,而 ByteQueue 则是用链表实现的
1.使用 SecBlock 类可以动态分配指定字节数的内容,并在类析构时自动释放,而且可以作为指定类的指针使用,有些方面类似于 auto_ptr
?五、椭圆曲线加密(ECIES)、签名(ECDSA)算法
1.ECIES
构造方法
AutoSeededRandomPool rng;// 随机数产生器
ECIES::Decryptor cpriv(rng, ASN1::sect193r1());// 私钥,自己保留
ECIES::Encryptor cpub(cpriv);// 公钥,提供给用户
注意:椭圆曲线加密算法是拥有公钥的人将数据加密后,密文发送给自己,自己来解密,所以不适用于注册码的生成
2.ECDSA
以下描述一个自定义的椭圆曲线的构造过程(以GF(p)上的椭圆曲线为例),参数可从以下网址得到http://www.cryptomathic.dk/labs/ellipticcurvedemo.html
//
Integer modulus("199999999999999999999999980586675243082581144187569");
// a、b为椭圆曲线参数
Integer a("659942,b7261b,249174,c86bd5,e2a65b,45fe07,37d110h");
Integer b("3ece7d,09473d,666000,5baef5,d4e00e,30159d,2df49ah");
// 计算基点G的两个参数x、y
Integer x("25dd61,4c0667,81abc0,fe6c84,fefaa3,858ca6,96d0e8h");
Integer y("4e2477,05aab0,b3497f,d62b5e,78a531,446729,6c3fach");
Integer r("100000000000000000000000000000000000000000000000151");
Integer k(2);
// 私有密钥
Integer d("76572944925670636209790912427415155085360939712345");
?// 椭圆曲线
ECP ec(modulus, a, b);
// P为基点G
ECP::Point P(x, y);
// 计算基点G
P = ec.Multiply(k, P);
// Q为公开密钥
ECP::Point Q(ec.Multiply(d, P));
ECIES::Decryptor cpriv(ec, P, r, d);
ECIES::Encryptor cpub(cpriv);
ECDSA::Signer spriv(cpriv);
ECDSA::Verifier spub(spriv);
ECDH::Domain ecdhc(ec, P, r, k);
ECMQV::Domain ecmqvc(ec, P, r, k);
3.椭圆曲线上的点的阶(Order of point)
椭圆曲线的签名的长度是由基点P的阶的长度决定的,和素数的长度无关。所以椭圆曲线可以选取素数较大的类型。
4.椭圆曲线的密钥
私钥是一个大数,而公钥则是一个点
密码类库Crypto++™ Library 5.1的研究与应用
密码类库Crypto++? Library 5.1的研究与应用
摘要
引言
在计算机被广泛应用的信息时代,信息本身就是时间,就是财富。大量信息用数据形式存放在计算机系统里。信息的传输则通过公共信道。这些计算机系统和公共信道是不设防的,是很脆弱的,容易受到攻击和破坏,信息的丢失不容易被发现,而且后果是极其严重。如何保护信息的安全已不仅仅是军事和政府部门感兴趣的问题,其他企事业单位也愈感迫切。因为在网络化的今天,计算机犯罪每年使他们遭受的损失极其巨大,而且还在发展中。密码是有效而且可行的保护信息安全的办法。随着计算机网络不断渗透到各个领域,密码学的应用也随着扩大。数字签名、身份鉴别、等都是由密码学派生出来的新技术和应用。目前开放源代码的加密库中,密码类库Crypto++是比较流行的,目前的最高版本为Crypto++? Library 5.1,它实现了各种公开密钥算法、对称加密算法、数字签名算法、信息摘要算法以及其相关的其它算法等等,Crypto++? Library 5.1几乎包括了目前所有安全算法库,对密码类库Crypto++? Library 5.1的研究与应用对计算机网络安全的研究与发展有重大的实际意义。
(一)Crypto++? Library 5.1要求的密码知识
Crypto++? Library 5.1要求什么样的密码知识基础呢,很多初学者都想知道这个问题。然而当你提出一个基础的问题在别处找到答案,你会发现这对你没有多大用处,因为越来越多熟练使用这个类库包的人不仅仅是考虑挑战安全问题。
该密码库的建立是假设你对密码术语已经有一定的了解的基础上的,如果你已经达到这一点,你可以进行一些比较基础的研究,到那时你会发现即使在最有利的情况下建立一个安全体系也是很困难的。如果你可以克服这些困难去研究这方面知识,你可以从一些网站获得比较专业的帮助。
Crypto++库包含有大量的算法,但是它们对用户来说并不总是显而易见的,下面推荐一些算法,因为这些算法不但用得很广,而且被公认比较安全的,并且是免费的。
1、 分组密码:DES-EDE3, Blowfish, Rijndael
2、 序列密码:
3、 Hash函数:SHA1
4、 消息认证码: HMAC/SHA1
5、 公钥加密:RSA/OAEP/SHA1
6、 签名:RSA/PKCS1v15/SHA1, DSA, Generalized-DSA/SHA1
7、 密钥协议:DH
8、 随机数产生器:RandomPool, AutoSeededRandomPool
(二)密码类库Crypto++? Library 5.1的内容
Crypto++ 库是一个用c++ 编写的密码类库,是一个自由软件。Crypto++? Library 5.1于2003年3月22日发布,是目前最高的版本,该版本加入了除了作者Wei Dai以外的另外一些作者的代码重新包装成类,类库里主要包含下列的内容:
1、 用抽象类定义API类的继承层次
2、 高级加密标准AES(Advanced Encryption Standard) Rijndael和AES候选算法:RC6, MARS, Twofish, Serpent, CAST-256
1997年4月15日美国国家标准技术研究所NIST发起征集高级加密标准AES算法的活动,目的是为确定一个安全性能更好的分组密码算法用于取代DES,AES的基本要求是比三重DES快并且至少与DES一样安全,分组长度为128位,密钥长度为128位,192位或256位.2001年11月26日,NIST正式公布高级加密标准AES, AES的安全性能是良好的,经过多年来的分析和测试,至今没有发现AES的明显缺点,也没有找到明显的安全漏洞. AES能够抵抗目前已知的各种攻击方法的攻击。
3、 对称分组密码:IDEA, DES, Triple-DES (DES-EDE2 and DES-EDE3), DESX (DES-XEX3), RC2, RC5, Blowfish, Diamond2, TEA, SAFER, 3-WAY, GOST, SHARK, CAST-128, Square, Skipjack。
分组密码又称为秘密钥密码或对称密码。利用分组密码对明文进行加密时,首先需要对明文进行分组,每组的长度都相同,然后对每组明文分别加密得到等长的密文,分组密码的特点是加密密钥与解密密钥相同。分组密码的安全性应该主要依赖于密钥,而不依赖于对加密算法和解密算法的保密。因此,分组密码的加密和解密算法可以公开。
4、 一般的密码模式:ECB, CBC, CBC ciphertext stealing (CTS), CFB, OFB, counter mode (CTR) 。
电子密本(ECB), 密码分组链接(CBC),输出反馈(OFB)和密文反馈(CFB)
5、 序列密码:Panama, ARC4, SEAL, WAKE, WAKE-OFB, BlumBlumShub
序列密码可以认为是起源于20世纪20年代的Vernam体系,当Vernam体制中的密钥序列是随机的(0,1)时,他就是“一次一密“密码体制。Shannon已经证明了“一次一密“密码体制在理论上是不可破译的。由于随机的密钥序列产生、存储以及分配等方面存在一定的困难,Vernam体制在当时并没有得到广泛的应用。随着微电子技术和数学理论的发展与完善,基于伪随机序列的序列密码得到了长足的发展和应用。在序列密码中,加密和解密所用的密钥都是伪随机序列,伪随机序列的产生比较容易并且有比较成熟的数学理论工具,目前,序列密码是 世界各国的军事和外交等领域中使用的主要密码体制之一。
6、 公钥密码: RSA, DSA, ElGamal, Nyberg-Rueppel (NR), Rabin, Rabin-Williams (RW), LUC, LUCELG, DLIES (variants of DHAES), ESIGN
在公钥密码体制中加秘密钥和解密密钥是不一样的,加密密钥可以公开传播而不危及密码体制的安全性。
RSA公钥密码体制的安全性是基于大整数的素分解问题的难解性,
7、公钥密码系统补丁:PKCS#1 v2.0, OAEP, PSSR, IEEE P1363 EMSA2
8、密钥协商方案:Diffie-Hellman (DH), Unified Diffie-Hellman (DH2), Menezes-Qu-Vanstone (MQV), LUCDIF, XTR-DH
9、椭圆曲线密码:ECDSA, ECNR, ECIES, ECDH, ECMQV
9、 单向hash函数:
hash函数是一种将一种任意长度的消息(message)压缩为某一固定长度的消息摘要(message digest)的函数。hash函数可以用于数字签名和消息的完整性检测。
SHA-1,:
安全hash算法SHA
MD2, MD4, MD5, HAVAL, RIPEMD-160, Tiger, SHA-2 (SHA-256, SHA-384, and SHA-512), Panama
11、消息认证码(MAC):MD5-MAC, HMAC, XOR-MAC, CBC-MAC, DMAC
12、基于密码结构的Hash函数:Luby-Rackoff, MDC
13、伪随机数发生器(PRNG): ANSI X9.17 appendix C, PGP's RandPool
14、password based key derivation functions:PBKDF1 and PBKDF2 from PKCS #5
15、压缩和解压算法
16、大整数和多项式快速精确算法
17、有限范围内的算法包括GF(p) 和 GF(2^n)
18、素数的产生和验证
等等。
(三)密码类库Crypto++? Library 5.1的开发过程
Crypto++密码类库自从发布以来,作为一个自由软件,得到广大开发者的支持,吸收了很多优秀的算法和原代码,一直在不断的在完善和扩大,适应了各种常用的操作系统和编译平台。
(四)密码类库Crypto++? Library 5.1的编译平台
Crypto++? Library 5.1 支持多种操作系统和各种各样的编译平台,但是对于有些操作系统下的一些编译平台要添加一定的补丁,下面我们就把一些常用的操作系统和编译平台的编译情况列出来如下:
开发环境
操作系统
编译Crypto++ 4.2
编译Crypto++ 5.0
编译Crypto++ 5.1
MSVC 6.0 SP5
WIN32
可直接编译
可直接编译
MSVC .NET 2002
WIN32
可直接编译
MSVC .NET 2003
WIN32
没有测试
要有效的补丁
Borland C++Builder 6
WIN32
没有测试
GCC 2.95.2
UNIX/WIN32/BeOS/
MSDOS(DJGPP2.03)
可直接编译
GCC 3.2
UNIX/WIN32/BeOS
要有效的补丁
可直接编译
Apple GCC 932.1 (2.95.2)
MacOS X (Darwin)
要有效的补丁
要有效的补丁
可直接编译
Apple GCC 1161 (3.1)
没有测试
CodeWarrior Pro 6.1
MacOS/WIN32
需要有效的工程文件可直接编译
没有测试
CodeWarrior Pro 8.2
没有测试
需要有效的工程文件
Sun WorkShop 6, Forte C++
Solaris
没有测试
没有测试
(五)密码类库Crypto++? Library 5.1的类库分析
密码库是用了高层的c++特征,如模板,多重继承和异常等一流的强有力的工具来实现各种各样错综复杂的密码算法
For people who are familiar with C++, the library will appear intuitive and easy to use. Others may need to view it as a learning opportunity. If you are a C++ beginner and you are under a very tight schedule, or if you are "afraid" of the more advanced features of C++, this library may not be for you. Having said that, you are invited to see for yourself how easy or hard it is to use by looking at some of the other answers in this category.
对熟悉c++的用户来说很容易用,
下载:
Where is the tutorial?
Where is the reference manual?
Is there anyone I could pay to help me with this?
How am I going to use Crypto++ if I don't have a clue about cryptography?
Recommended Algorithms
There is nothing the more experienced people that use this library like more than a challenging security question to mull over. However, you may find you don't get much help if you ask a basic question with an answer that is well-documented elsewhere.
The library assumes you know in cryptographic terms what you want to achieve. Until you reach that point, perhaps you should do some background research? You should also know that building secure systems is difficult at the best of times. If you can afford it, you can get some professional help: Is there anyone I could pay to help me with this?
The good news is that there is a decent body of literature to help you. A list of recommended cryptography books is available at http://books.cryptopp.com. A lot of good crypto information is also available on the web. See http://links.cryptopp.com for a list of recommended sites.
Crypto++ contains a large number of algorithms, and it may not always be obvious which ones to use. The algorithms given below are recommended because they are widely used and generally considered to be secure and patent-free.
block cipher: DES-EDE3, Blowfish, Rijndael
stream cipher: MARC4 (ARC4 with first 256 bytes of keystream discarded), any of the above block ciphers in CTR mode
hash function: SHA1
message authentication code: HMAC/SHA1
public key encryption: RSA/OAEP/SHA1
signature: RSA/PKCS1v15/SHA1, DSA, Generalized-DSA/SHA1
key agreement: DH
random number generator: RandomPool, AutoSeededRandomPool
10、
Crypto++ Library is a free C++ class library of cryptographic schemes. Currently the library consists of the following, some of which are other people's code, repackaged into classes.
?a class hierarchy with an API defined by abstract base classes
?AES (Rijndael) and AES candidates: RC6, MARS, Twofish, Serpent, CAST-256
?other symmetric block ciphers: IDEA, DES, Triple-DES (DES-EDE2 and DES-EDE3), DESX (DES-XEX3), RC2, RC5, Blowfish, Diamond2, TEA, SAFER, 3-WAY, GOST, SHARK, CAST-128, Square, Skipjack
?generic cipher modes: ECB, CBC, CBC ciphertext stealing (CTS), CFB, OFB, counter mode (CTR)
?stream ciphers: Panama, ARC4, SEAL, WAKE, WAKE-OFB, BlumBlumShub
?public key cryptography: RSA, DSA, ElGamal, Nyberg-Rueppel (NR), Rabin, Rabin-Williams (RW), LUC, LUCELG, DLIES (variants of DHAES), ESIGN
?padding schemes for public-key systems: PKCS#1 v2.0, OAEP, PSSR, IEEE P1363 EMSA2
?key agreement schemes: Diffie-Hellman (DH), Unified Diffie-Hellman (DH2), Menezes-Qu-Vanstone (MQV), LUCDIF, XTR-DH
?elliptic curve cryptography: ECDSA, ECNR, ECIES, ECDH, ECMQV
?one-way hash functions: SHA-1, MD2, MD4, MD5, HAVAL, RIPEMD-160, Tiger, SHA-2 (SHA-256, SHA-384, and SHA-512), Panama
?message authentication codes: MD5-MAC, HMAC, XOR-MAC, CBC-MAC, DMAC
?cipher constructions based on hash functions: Luby-Rackoff, MDC
?pseudo random number generators (PRNG): ANSI X9.17 appendix C, PGP's RandPool
?password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5
?Shamir's secret sharing scheme and Rabin's information dispersal algorithm (IDA)
?DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and zlib (RFC 1950) format support
?fast multi-precision integer (bignum) and polynomial operations
?finite field arithmetics, including GF(p) and GF(2^n)
?prime number generation and verification
?various miscellaneous modules such as base 64 coding and 32-bit CRC
?class wrappers for these operating system features (optional):
?high resolution timers on Windows, Unix, and MacOS
?Berkeley and Windows style sockets
?Windows named pipes
?/dev/random and /dev/urandom on Linux and FreeBSD
?Microsoft's CryptGenRandom on Windows
?A high level interface for most of the above, using a filter/pipeline metaphor
?benchmarks and validation testing
One purpose of Crypto++ is to act as a repository of public domain (not copyrighted) source code. Although the library is copyrighted as a compilation, the individual files in it (except for a few exceptions listed in the license) are in the public domain.
?2003年4月22日增加了开发环境CodeWarrior Pro8.2 固定的工程文件
?增加 VS.NET 2003 的补丁
?发布Crypto++? Library 5.1 版本
?4/22/2003 - Added fixed project file for CodeWarrior Pro 8.2
?4/19/2003 - Added patch for VS .NET 2003
?3/22/2003 - Version 5.1 release.
?added PSS padding and changed PSSR to track IEEE P1363a draft standard
?added blinding for RSA and Rabin to defend against timing attacks on decryption operations
?changed signing and decryption APIs to support the above
?changed WaitObjectContainer to allow waiting for more than 64 objects at a time on Win32 platforms
?fixed a bug in CBC and ECB modes with processing non-aligned data
?fixed standard conformance bugs in DLIES (DHAES mode) and RW/EMSA2 signature scheme (these fixes are not backwards compatible)
?fixed a number of compiler warnings, minor bugs, and portability problems
?removed Sapphire
?3/10/2003 - Updated patch for MacOS X (Darwin)
?10/4/2002 - Version 5.0 has been imported into CVS, with modulename "c5"
?10/1/2002 - Added updated CodeWarrior 8 project file from Aparajita Fishman.
?9/30/2002 - Version 5.0 released.
?added ESIGN, DLIES, WAKE-OFB, PBKDF1 and PBKDF2 from PKCS #5
?added key validation for encryption and signature public/private keys
?renamed StreamCipher interface to SymmetricCipher, which is now implemented by both stream ciphers and block cipher modes including ECB and CBC
?added keying interfaces to support resetting of keys and IVs without having to destroy and recreate objects
?changed filter interface to support non-blocking input/output
?changed SocketSource and SocketSink to use overlapped I/O on Microsoft Windows
?grouped related classes inside structs to help templates, for example AESEncryption and AESDecryption are now AES::Encryption and AES::Decryption
?where possible, typedefs have been added to improve backwards compatibility when the CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY macro is defined
?changed HAVAL and IDEA to use public domain code
?implemented SSE2 optimizations for Integer operations
?is being evaluated for FIPS 140-2 compliance
?fixed a bug in HMAC::TruncatedFinal()
?fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02
?8/26/2002 - Added porting note for Sun WorkShop 6 with Forte C++
(四)密码类库Crypto++? Library 5.1的编译平台
These porting notes will help you compile Crypto++ on various platforms. If you need to compile Crypto++ 4.1 or earlier, please click here.
开发环境
操作系统
编译Crypto++ 4.2
编译Crypto++ 5.0
编译Crypto++ 5.1
MSVC 6.0 SP5
WIN32
no changes needed
no changes needed
Processor Pack supported/recommended
MSVC .NET 2002
WIN32
no changes needed
MSVC .NET 2003
WIN32
not tested
patch available
Borland C++Builder 6
WIN32
not tested
GCC 2.95.2
UNIX/WIN32/BeOS/
MSDOS (DJGPP 2.03)
no changes needed
GCC 3.2
UNIX/WIN32/BeOS
patch available
no changes needed
Apple GCC 932.1 (2.95.2)
MacOS X (Darwin)
patch available
patch available
no changes needed
Apple GCC 1161 (3.1)
not tested
CodeWarrior Pro 6.1
MacOS/WIN32
no changes needed
project file available
not tested
CodeWarrior Pro 8.2
not tested
updated project file by Aparajita Fishman
fixed project file available
Sun WorkShop 6, Forte C++
Solaris
note and diff by David Lamkin
not tested
Remember to use the "-a" (auto-convert text files) option when unzipping on a Unix machine. The zip files should have the following hashes:
crypto42.zip:
MD5: C1700E6E15F3189801E7EA47EEE83078SHA-1: 505EC40485519971A07DF6708B7DED3E5D3D08C4RIPEMD-160: 5D4CC8E5987B2416CF7D71AA6276AFAC61702E55SHA-256: CDF8A1EBB142759E928A323F47F228F4F93CEB2FE97C19DC59D6868989E0D76Ecrypto50.zip:
MD5: fe8d4ef49b69874763f6dab30cbb6292SHA-1: d0d83e60b6c03408370ca6c13aa5cac5e2220bf1RIPEMD-160: 150db13d4df29020829f0fe817f54ee5a0595e50SHA-256: c67c64693f32195e69d3d7e5bdf47afbd91e8b69d0407a2bc68a745d9dbebb26crypto51.zip:
MD5: f4bfd4ac39dc1b7f0764d61a1ec4df16SHA-1: 95905714c85f6fb563e66edb5478818df787fe2dRIPEMD-160: 8b7420c421be39e9976f1ce2a80840d7ed6b38efSHA-256: d183a98c28feb1e0f7d21d177469831e5052aa8ca446475e95a5ebe7a7feb3cd I get an "error opening file" message when I run cryptest.exe.
Why can't I read Crypto++ objects from files via FileStore with STLport streams?
I'm getting the error message "Cryptographic algorithms are disabled after power-up a self test failed" or something about "edc.dat".
Microsoft tools
I compiled cryptest.exe successfully, but am getting linker errors with my own application.
I'm getting internal compiler errors on Windows 98.
Others
Can I use Crypto++ with <insert compiler name here>?
I am getting compiler errors with GCC or EGCS.
GCC is using an enormous amount of memory to compile Crypto++.
I'm getting an "as" (assembler) error on Solaris.
Crypto++4.2 and STLPort 4.53
Is it possible to supply a prime modulus as it is with ElGamal key generation to other PK algorithms like RSA and DH in order to decrease their key generation times? If so can you supply example code to do just this?
How to output a Integer as string(Decimal/Hex)?
(五)密码类库Crypto++? Library 5.1的使用
The library is an powerful and elegant tool for performing complex cryptography. It uses advanced C++ features such as templates, multiple inheritance, and exceptions to achieve that power and elegance.
For people who are familiar with C++, the library will appear intuitive and easy to use. Others may need to view it as a learning opportunity. If you are a C++ beginner and you are under a very tight schedule, or if you are "afraid" of the more advanced features of C++, this library may not be for you. Having said that, you are invited to see for yourself how easy or hard it is to use by looking at some of the other answers in this category.
对熟悉c++的用户来说
How much C++ experience do I need to use this library?
How do I use the Filter class?
How do I use hex encoding and decoding?
How do I use a block cipher in Crypto++ 4.2?
How do I use a block cipher in Crypto++ 5.0?
How do I use a stream cipher?
How do I use a hash function?
How do I use a message authentication code?
How do I use a random number generator?
How do I use a public key cryptosystem or signature scheme?
How can I use an RSA key from Crypto++ in openssl?
The sample code shows how to work with a file, but my data is in a string (or vice versa).
Why is ElGamal key generation so slow?
I'm trying to process multiple messages with a Filter, and MaxRetrievable() always returns 0 after the first one.
(六)密码类库Crypto++? Library 5.1的类库分析
见:CryptoManual _index.htmClass Hierarchy、 Compound List
模板类、抽象类、类
(七)密码类库Crypto++? Library 5.1的应用实例(1)
现在我们就来研究一下对这个库的用法我们在win32的操作系统下用vc6++来编译Crypto++? Library 5.1 的源代码,在对应的目录下会产生文件夹Debug,在文件夹Debug里,会有一个编译好的静态库文件 cryptlib.lib 我们就来研究什么用这个静态库文件。
Hash函数的应用
Links to cryptographic resources - http://www.mobiuslinks.com/links.asp?sid=1
Administration
How can I contribute to this FAQ?
While You Are Downloading
?Take a look at the related links page. It includes links to crypto libraries for other languages, products that use Crypto++, etc.
?Consider the list of recommended books for Crypto++ users.
?Examine the Crypto++ license agreement.
?Read denis bider's Crypto++ User Guide
?Browse the Crypto++ Reference Manual (mirrored here).
?View these Crypto++ class hierarchy charts to see how Crypto++ is organized. Note that these charts only include a small number of actual algorithms as examples.
?symmetric algorithms and hash functions
?public key algorithms
Mailing Lists
There are two mailing lists for Crypto++.
?cryptopp-announce@lists.sourceforge.net - Crypto++ announcements
?cryptopp-list@eskimo.com - user questions and general discussion related to Crypto++, archived at http://www.escribe.com/software/crypto. Send an email to mailto:cryptopp-list-request@eskimo.com?subject=subscribe with the subject "subscribe" to subscribe, and use "unsubscribe" subject to unsubscribe. When posting a question to the mailing list, please give the following information, if available:
?exact error message
?stack trace
?a minimal program with a main() function, that reproduces the problem
?versions of Crypto++, operating system (output of "uname -a" command if using Unix), and compiler (output of "gcc -v" if using GCC)
To Contribute
The Crypto++ source code and FAQ are hosted on .
?The SourceForge CVS Repository allows you to view the latest (unreleased) Crypto++ source code and to contribute bug fixes or new features. The CVS repository contains two modules:
?src - version 4.x and earlier.
?c5 - version 5.x.
?The Crypto++ Faq-O-Matic allows you to view frequently asked questions and to contribute new questions or answers.
Paid Support and Consulting
If you are interested in paid support for Crypto++ or consulting on a Crypto++ related project, please take a look at this list of companies and individuals providing such services. This listing is a free service for the Crypto++ community, and anyone may sign up to be listed by following the above link.
Crypto++的静态连接库及其在Win32平台下的使用
在win32的操作系统下用vc6++来编译Crypto++? Library 5.1 的源代码,在对应的目录下会产生文件夹Debug,在文件夹Debug里,会有一个编译好的静态库文件cryptlib.lib;下面通过实例研究这个静态库文件的使用:
在应用lib文件时先把库里的头文件和lib文件复制到工程的目录里这是最好的方法,或者把它们放到一个文件夹里修改指定的include 目录,即在菜单Tools中选Options,在Options的对话框里选Directories 在include files和Library files 的页面添加指向该文件夹的路径。
3.1、Hash函数的应用:
Hash函数的最基本的用法就是计算Hash值,一个Hash函数是一个多对一的映射,可以输入任意长度的消息,输出却是一个固定长度的消息,而且,只要有一点很微小的差异的两个消息之间的Hash值也会有很大的差异,根据两个不同的Hash值就可以判断对应的两个消息是不同的。所以Hash函数通常用于数字签名和消息的完整性检测等等一些安全性方面的应用。下面举一个计算字符串的Hash值简单的例子。
#pragma comment (lib,"cryptlib.lib") //加载lib文件的语句
#include "md5.h"
#include <iostream>
using namespace CryptoPP; //使用名字空间CryptoPP
using namespace std; //使用名字空间std
void main(){
byte message[128]; byte m[16];
cout<<"输入字符串"<<endl; cin.getline((char*) message,128);
MD5 md5; md5.Update(message,128); md5.Final(m);
for(int i=0;i<16;i++)printf("%02x",m[i]);printf(" ");
}
这个例子首先生成MD5对象(类MD5在md5.h里定义),调用方法Update()和Final(),这两个方法是定义在基类HashTransformation里的。void Update (const byte *input, unsigned int length) 是用来处理输入的方法,input 是byte型是将要计算Hash值的字符串,length是字符串的长度。void Final (byte *digest) 是计算当前消息的Hash值并重新开始新的消息的方法,digest是用来存放Hash值的byte型数组。
HashTransformation还定义了几个常用的方法 void CalculateDigest (byte *digest, const byte *input, unsigned int length)也是用来计算hash值的方法,可以用md5. CalculateDigest(m,message,128),来替换上面例子md5.Update(message,128)与 md5.Final(m) 这两个语句。
在消息完整性检测方面我们通常都是检测文件的完整性,一个相当大的文件如果对其进行一个很微小的修改我们根本看不出的,但是它们的Hash值却有很大的变化,所以我们只要比较Hash值就很容易看出该文件是否为原来的文件。计算文件的Hash值在这个密码库的支持下就比较简单就用下面的一行代码就行了
FileSource f(file, true, new HashFilter(md5,
new HexEncoder(new ArraySink(buffer,2 * MD5::DIGESTSIZE))));
这一行代码总共用了4个类ArraySink、HexEncoder、HashFilter和FileSource。首先用类ArraySink复制一个2 * MD5::DIGESTSIZE 字节的buffer存储缓冲区,接着用类HexEncoder把这个缓冲区转换为16进制。计算Hash值主要用到类HashFilter。类FileSource是把要计算Hash值的文件file进行一定的转换放入临时缓冲区,然后调用实例化的HashFilter对其进行计算相应Hash函数的Hash值。
3.2 对称密码的应用我们说明DES的编程。DES有四种工作模式:电子密码本模式(electronic codebook mode),密码分组链接模式(cipher block chaining mode),密码反馈模式(cipher feedback mode)以及输出反馈模式(output feedback mode)。
应用对称密码首先我们要确定用那种工作模式,即用ECB, CBC, CFB和OFB中的那种模式。Crypto++提供的工作模式对象,其本质上是把分组密码(block cipher)转换成序列密码(stream cipher)。下面就是创建工作模式CFB的例子:
byte key[AES::DEFAULT_KEYLENGTH], iv[AES::BLOCKSIZE];CFB_Mode<AES >::Encryption cfbEncryption(key, AES::DEFAULT_KEYLENGTH, iv);
其中iv 是一个增量值,可以随便取一个字符串。
知道什么创建工作模式后我们就通过具体的例子来研究对称密码的用法。下面我们来看高级加密标准AES在工作模式CFB下的简单应用。
string AESEncryptString(const char *instr, const char *passPhrase) // AES加密字符串函数{ std::string outstr; byte iv[AES::BLOCKSIZE]="123456"; AES::Encryption aesEncryption((byte *)passPhrase, AES::DEFAULT_KEYLENGTH);CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv); StreamTransformationFilter cfbEncryptor(cfbEncryption, new HexEncoder(new StringSink(outstr))); cfbEncryptor.Put((byte *)instr, strlen(instr)); cfbEncryptor.MessageEnd(); return outstr;}string AESDecryptString(const char *instr, const char *passPhrase)// AES解密字符串函数{ std::string outstr; byte iv[AES::BLOCKSIZE]="123456"; CFB_Mode<AES >::Decryption cfbDecryption((byte *)passPhrase, AES::DEFAULT_KEYLENGTH, iv); HexDecoder decryptor(new StreamTransformationFilter(cfbDecryption, new StringSink(outstr))); decryptor.Put((byte *)instr, strlen(instr)); decryptor.MessageEnd(); return outstr;}在应用这两个函数时要加三个头文件 aes.h、hex.h和modes.h。加密函数string AESEncryptString(const char *instr, const char *passPhrase)中参数instr是要加密的字符串,passPhrase是密钥。这个函数的基本流程为:先用密钥passPhrase初始化一个AES的加密对象aesEncryption,然后用aesEncryption和增值量iv创建一个加密的CFB工作模式,iv是可以随便取一个字符串,但是要注意加密使用的iv要和解密的一样,否则解密不了。这里我们用了一个流过滤器StreamTransformationFilter对工作模式进行包装, StreamTransformationFilter可以作为一个Filter对象。StreamTransformationFilter将在需要的时候将缓冲区数据阻塞。为了让输出的密文比较直观,我们在处理输出时用十六进制输出,所以我们在这里用了转换为十六进制的类HexEncoder。方法Put()是对输入进行处理,然后调用上面的加密对象对字符串进行加密,方法MessageEnd()是输入的结束性标志。解密函数string AESDecryptString(const char *instr, const char *passPhrase) 中参数instr是要解密的密文,passPhrase是密钥。解密函数的基本流程和加密的差不多,只是用到的类和加密的是相对的。用密钥passPhrase和iv创建一个AES解密的CFB工作模式对象cfbDecryption,然后用流过滤器StreamTransformationFilter对工作模式进行包装,用转化十六进制为byte型的类HexDecoder对对象进行转化得出对象decryptor,再调用方法Put()对输入进行处理,然后调用上面的加密对象对字符串进行解密。现在我们就用这两个函数对字符串“贵州大学计算机软件与理论研究所 Guizhou University”进行加解密,密钥我们用“guizhoudaxue”,在vc6编译平台下,运行结果为:
由于AES加密速度比较快、效率高而且比较安全,所以我们通常用来对文件进行加解密,下面我们就来看加解密文件的例子。
void AESEncryptFile(const char *in, const char *out, const char *passPhrase)//加密文件
{
byte iv[AES::BLOCKSIZE]="123456";
AES::Encryption aesEncryption((byte *)passPhrase, AES::DEFAULT_KEYLENGTH);
CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);
FileSource
f(in, true, new StreamTransformationFilter(cfbEncryption, new FileSink(out)));
}
void AESDecryptFile(const char *in, const char *out, const char *passPhrase)//解密文件
{
byte iv[AES::BLOCKSIZE]="123456";
CFB_Mode<AES >::Decryption cfbDecryption((byte *)passPhrase, 16, iv);
FileSource
f(in, true, new StreamTransformationFilter(cfbDecryption, new FileSink(out)));
}
在应用这两个函数时要加四个头文件 aes.h、hex.h、files.h和modes.h。加密函数void AESEncryptFile(const char *in, const char *out, const char *passPhrase)中参数in是要加密的文件名,out是要解密的文件名,passPhrase是密钥。这个函数的基本流程为:先用增量值iv和密钥passPhrase创建一个AES加密的CFB工作模式对象aesEncryption。
下面来看在工作模式CBC下用DES-EDE对字符串加解密的简单例子。下面给出两个函数。
string EncryptString(const char *instr, const char *passPhrase){ //加密函数
string outstr;
DefaultEncryptorWithMAC //生成对象
encryptor(passPhrase, new HexEncoder(new StringSink(outstr)));
encryptor.Put((byte *)instr, strlen(instr)); encryptor.MessageEnd(); return outstr;
}
string DecryptString(const char *instr, const char *passPhrase){ //解密函数
string outstr;
HexDecoder
decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr)));
decryptor.Put((byte *)instr, strlen(instr)); decryptor.MessageEnd(); return outstr;
}
加密函数string EncryptString(const char *instr, const char *passPhrase) 中instr是要加密的字符串,passPhrase是用来加密的密钥。这个函数用了密码库里的四个类DefaultEncryptorWithMAC、HexEncoder和StringSink。StringSink 是类StringSinkTemplate<std::string>的一个实例化,主要作用是添加输入到一个字符串对象。HexEncoder在hex.h里定义是用来转换所给的数据为十六进制。DefaultEncryptorWithMAC在default.h里定义,是用DES-EDE2 和 HMAC/SHA-1 在密钥下进行加密,Put()和MessageEnd()是这个类的两个基本的方法。unsigned int Put (const byte *inString, unsigned int length, bool blocking=true)是用来处理输入多重的字节,bool MessageEnd (int propagation=-1, bool blocking=true)用来作为输入消息的结束标志。这个函数的基本流程是:首先用类StringSink 把outstr添加到一个String对象,接着用HexEncoder把这个对象转换为十六进制。然后用加密密钥passPhrase产生一个DefaultEncryptorWithMAC对象encryptor,最后调用encryptor的方法Put()来处理输入instr进而对其进行加密,把加密后的密文放到outstr。
解密函数string DecryptString(const char *instr, const char *passPhrase) 中instr是要解密的字符串,passPhrase是用来解密的密钥,跟加密的密钥要相同。也用了三个类HexDecoder、DefaultDecryptorWithMAC和StringSink。HexDecoder是把给定的十六进制数据转换成为byte型。DefaultDecryptorWithMAC 也是定义在default.h文件里与类DefaultEncryptorWithMAC相应的是用来解密。这个函数的基本流程是:首先用类StringSink 把outstr添加到一个String对象,然后用解密密钥passPhrase产生一个DefaultDecryptorWithMAC对象,利用类HexDecoder对DefaultDecryptorWithMAC对象进行数据转换生成对象decryptor,然后利用decryptor的方法Put()进行输入处理,进而进行解密,把解密后的明文放到outstr。
现在我们就来用上面的两个函数对字符串“贵州大学计算机软件与理论研究所 Guizhou University“用密钥“guizhoudaxue“进行加密和解密,其运行结果如下:
3.3、公钥密码的应用
RSA虽然很安全,但是最困难的就是要产生两个很大的素数,这样才会生成公钥和密钥。Crypto++密码库提供一些大整数的快速运算,还有高效的概率素数测试,运用这个库很容易找出足够大的素数;我们通过例子就来研究
产生公钥密码RSA的密钥和公钥文件。
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)//产生公钥密钥文件
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
HexEncoder privFile(new FileSink(privFilename)); //打开文件实行序列化操作
priv.DEREncode(privFile); //写密码对象priv到文件对象privFile里
privFile.MessageEnd();
RSAES_OAEP_SHA_Encryptor pub(priv);
HexEncoder pubFile(new FileSink(pubFilename));
pub.DEREncode(pubFile);
pubFile.MessageEnd();
}
函数void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)是用来产生密钥和公钥文件。参数keyLength是密钥长度。PrivFilename是存放密钥的文件名,pubFilename是存放公钥的文件名,seed时产生密钥的种子。该函数首先用类RandomPool的方法Put()产生种子seed的byte型伪随机数。RSAES_OAEP_SHA_Decryptor是一个解密的公钥密码系统在文件rsa.h 有如下定义:
typedef RSAES<OAEP<SHA> >::Decryptor RSAES_OAEP_SHA_Decryptor;就是在这个类用前面产生的伪随机数和密钥长度keyLength生解密的密钥,然后通过类FileSink打开文件pubFilename实行序列化操作,用HexEncoder把它转换为十六进制,最后用方法DEREncode()把上面处理好的密码对象写入文件。这样就得到公钥密码的密钥文件了。产生公钥文件的方法和产生密钥文件不同的地方就是使用了RSAES_OAEP_SHA_Encryptor是一个加密的公钥密码系统,在文件rsa.h 有如下定义:
typedef RSAES<OAEP<SHA> >::Encryptor RSAES_OAEP_SHA_Encryptor;是用上面产生的密钥密码系统priv来生成相应公钥。
有了公钥密码的密钥和公钥文件后我们就可以用来对字符串进行加密和解密了,下面我们也给出了加密和解密的两个函数:
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)//加密
{
FileSource pubFile(pubFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Encryptor pub(pubFile);
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
string result;
StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
return result;
}
string RSADecryptString(const char *privFilename, const char *ciphertext)//解密
{
FileSource privFile(privFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Decryptor priv(privFile);
string result;
StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
return result;
}
加密函数string RSAEncryptString(const char *pubFilename, const char *seed, const char *message) 中pubFilename是公钥文件,seed是加密种子,message是要加密的字符串。这个函数的基本流程是:首先用类FileSource对公钥文件pubFilename进行一定的转换放入临时缓冲区,并把它从十六进制转换为byte型, 然后用FileSource的对象pubFile 实例化公钥密码系统RSAES_OAEP_SHA_Encryptor生成对象pub。用类RandomPool在种子seed下用方法Put()产生伪随机数,Seed可以任取。用类StringSink 把outstr添加到一个String对象,接着用HexEncoder把这个对象转换为十六进制。然后用伪随机数randPool、公钥密码系统pub和十六进制的String对象实例化一个公钥密码加密的过滤器,再用这个过滤器对字符串message进行加密把结果放到十六进制的字符串result里,这样就完成了对字符串的加密。解密函数的基本流程跟加密函数的基本流程差不多,就使用了几个不同的类,但是这些类跟加密函数的对应类的功能是相对的,很容易理解所以就不多加以解释了。
现在我们就来用公钥密码RSA对字符串“密码类库Crypto++ 5.1的应用研究“进行加密和解密(完整的原代码附加在后面)。我们先取密钥长keyLength为 1000,seed可以随便要一个字符串,然后调用产生密钥函数GenerateRSAKey()产生了公钥文件pub.txt和密钥文件priv.txt。有了密钥和公钥文件后我们就可以调用RSA的加密解密函数对字符串“贵州大学计算机软件与理论研究所 Guizhou University”进行加密解密了,其运行结果如下:
上一篇:windows开发首页
下一篇:duilib相关