Crypt++中文使用手册.docx

上传人:b****5 文档编号:8308089 上传时间:2023-01-30 格式:DOCX 页数:31 大小:39.12KB
下载 相关 举报
Crypt++中文使用手册.docx_第1页
第1页 / 共31页
Crypt++中文使用手册.docx_第2页
第2页 / 共31页
Crypt++中文使用手册.docx_第3页
第3页 / 共31页
Crypt++中文使用手册.docx_第4页
第4页 / 共31页
Crypt++中文使用手册.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

Crypt++中文使用手册.docx

《Crypt++中文使用手册.docx》由会员分享,可在线阅读,更多相关《Crypt++中文使用手册.docx(31页珍藏版)》请在冰豆网上搜索。

Crypt++中文使用手册.docx

Crypt++中文使用手册

Crypto++入门-安装

Crypto++是一个C++编写的密码学类库。

读过《过河卒》的朋友还记得作者的那个不愿意去微软工作的儿子吗,就是Crypto++的作者WeiDai。

Crypto++是一个非常强大的密码学库,在密码学界很受欢迎,最初还是Rivest(RSA的R)门下的一个博士姐姐把这个库介绍给我的。

虽然网络上可以找到很多密码学相关的代码和库,但是Crypto++有其明显的优点。

主要是功能全,统一性好。

例如椭圆曲线加密算法和AES在OpenSSL的crypto库中就还没最终完成,而在Crypto++中就支持的比较好。

基本上密码学中需要的主要功能都可以在里面找得到。

Crypto++是由标准的C++写成的,学习C++、密码学、网络安全都可以通过阅读Crypto++的源代码得到启发和提高。

Crypto++的安装

首先到上下载最新版本的源代码,如果是windows版的,会得到一个VC的项目,直接用VC打开就可以编译了。

这里建议大家使用最新版的C++编译器,因为诸如VC6的编译器是不支持C++的标准的,很多符合C++标准的代码不能编译通过。

编译的时间比较长,完成后会生成cryptlib.lib这个库文件。

可以将Crypto++源文件的目录命名为cryptopp,拷贝到编译器的include目录(例如:

C:

\VS.NET\VC7\include),将cryptlib.lib文件拷贝到编译器的lib目录。

这样我们只需要说明链接cryptlib.lib即可。

例如在VC7中在项目->属性->链接器->命令行->附加选项中添加“cryptlib.lib”。

HelloWorld

现在写一个helloworld程序看看能不能编译通过。

#include

usingnamespacestd;

#include

usingnamespaceCryptoPP;

intmain()

{

cout<<"hellocrypto++"<

cout<<"Aesblocksizeis"<

:

BLOCKSIZE<

return0;

}

编译运行,一切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文件,可以用WIN32API函数LoadLibrary、GetProcAddress。

事实上,我们可以在VisualC++IDE中以二进制形式打开lib文件,大多情况下会看到ASCII码格式的C++函数或一些重载操作的函数名字。

一般我们最主要的关于lib文件的麻烦就是出现unresolvedsymble这类错误,这就是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++库在VS2005中的使用——RSA加解密

一.下载Crypto++Library

Crypto++Library的官方网:

二.建立自己使用的Crypto++Library

由于从官方网下载的Crypto++库是开源的,只有源文件和几个可以生成lib、dll的工程,以及一个使用的例子工程,因此希望生成自己建的工程能使用的SDK。

1.编译链接生成cryptlib.lib

打开cryptest.sln,分别在Debug模式和Release模式下编译链接cryptlib工程,成功后会在cryptopp54\Win32\output\debug和cryptopp54\Win32\output\release下生成cryptlib.lib文件。

作者当时用的是Crypto++5.4版本。

Build时方法是,右击SolutionExplorer中的cryptlib工程,单击build。

第一次时它会报错说“d:

\cryptopp54\adler32.cpp(3):

fatalerrorC1033:

cannotopenprogramdatabase'd:

\cryptopp54\win32\cryptlib\debug\vc80.idb'”,没关系,按这样再build一次,就可以build成功了。

2.建立Crypto++SDK

在C:

\ProgramFiles\中新建文件夹,取名“CryptoPP”,里面新建文件夹“include”、“lib”,在“lib”中新建文件夹“debug”、“release”。

将Crypto++库中的所有头文件复制到“include”文件夹中,再将上面生成的两个cryptlib.lib分别复制到“debug”和“release”中。

三.RSA加解密

1.

在VS2005中新建Win32ConsoleApplication工程,建立空的工程。

完成后新建文件main.cpp,里面源码如下:

#include"randpool.h"

#include"rsa.h"

#include"hex.h"

#include"files.h"

#include

usingnamespacestd;

usingnamespaceCryptoPP;

#pragmacomment(lib,"cryptlib.lib")

//------------------------

//函数声明

//------------------------

voidGenerateRSAKey(unsignedintkeyLength,constchar*privFilename,constchar*pubFilename,constchar*seed);

stringRSAEncryptString(constchar*pubFilename,constchar*seed,constchar*message);

stringRSADecryptString(constchar*privFilename,constchar*ciphertext);

RandomPool&GlobalRNG();

//------------------------

//主程序

//------------------------

voidmain()

{

charpriKey[128]={0};

charpubKey[128]={0};

charseed[1024]={0};

//生成RSA密钥对

strcpy(priKey,"pri");//生成的私钥文件

strcpy(pubKey,"pub");//生成的公钥文件

strcpy(seed,"seed");

GenerateRSAKey(1024,priKey,pubKey,seed);

//RSA加解密

charmessage[1024]={0};

cout<<"OriginText:

\t"<<"HelloWorld!

"<

strcpy(message,"HelloWorld!

");

stringencryptedText=RSAEncryptString(pubKey,seed,message);//RSA加密

cout<<"EncryptedText:

\t"<

stringdecryptedText=RSADecryptString(priKey,encryptedText.c_str());//RSA解密

cout<<"DecryptedText:

\t"<

}

//------------------------

//生成RSA密钥对

//------------------------

voidGenerateRSAKey(unsignedintkeyLength,constchar*privFilename,constchar*pubFilename,constchar*seed)

{

RandomPoolrandPool;

randPool.Put((byte*)seed,strlen(seed));

RSAES_OAEP_SHA_Decryptorpriv(randPool,keyLength);

HexEncoderprivFile(newFileSink(privFilename));

priv.DEREncode(privFile);

privFile.MessageEnd();

RSAES_OAEP_SHA_Encryptorpub(priv);

HexEncoderpubFile(newFileSink(pubFilename));

pub.DEREncode(pubFile);

pubFile.MessageEnd();

}

//------------------------

//RSA加密

//------------------------

stringRSAEncryptString(constchar*pubFilename,constchar*seed,constchar*message)

{

FileSourcepubFile(pubFilename,true,newHexDecoder);

RSAES_OAEP_SHA_Encryptorpub(pubFile);

RandomPoolrandPool;

randPool.Put((byte*)seed,strlen(seed));

stringresult;

StringSource(message,true,newPK_EncryptorFilter(randPool,pub,newHexEncoder(newStringSink(result))));

returnresult;

}

//------------------------

//RSA解密

//------------------------

stringRSADecryptString(constchar*privFilename,constchar*ciphertext)

{

FileSourceprivFile(privFilename,true,newHexDecoder);

RSAES_OAEP_SHA_Decryptorpriv(privFile);

stringresult;

StringSource(ciphertext,true,newHexDecoder(newPK_DecryptorFilter(GlobalRNG(),priv,newStringSink(result))));

returnresult;

}

//------------------------

//定义全局的随机数池

//------------------------

RandomPool&GlobalRNG()

{

staticRandomPoolrandomPool;

returnrandomPool;

}

2.设置工程属性

选择工程属性(Alt+F7):

(1)“ConfigurationProperties”→“C/C++”→“General”,右边的“AdditionalIncludeDirectories”设置为上面建好的Crypto++SDK的Include文件夹,“C:

\ProgramFiles\CyptoPP\include”;

(2)“ConfigurationProperties”→“Linker”→“General”,右边的“AdditionalLibraryDirectories”设置为上面建好的Crypto++SDK的Lib\Debug文件夹,“C:

\ProgramFiles\CyptoPP\lib\debug”(Release模式下对应着Release文件夹);

(3)“ConfigurationProperties”→“C/C++”→“CodeGeneration”,右边的“RuntimeLibrary”设置为“Multi-threadedDebug(/MTd)”(Release模式下对应着“Multi-threaded(/MT)”)

3.运行程序(Ctrl+F5)

正常运行的输出结果为:

OriginText:

HelloWorld!

EncryptedText:

79C72A482482EF45111F961772456310792AB735ECF72329ECB26292D2B26374

824E0E35D24A63CB03B867DD2C70B001FD4B2B33FBC984BD229A5226F284B889901817976A680322

9E8351372C5E28E8BEBA2A94E7CF61A8A162F0BA2F3E0C35D26842D92EC4866D25E6BF878743E481

84D9F6FF9BA690F953568D017C02D540

DecryptedText:

HelloWorld!

如果上面的第(3)步没有设置则会出现以下链接错误:

cryptlib.lib(randpool.obj):

errorLNK2005:

"public:

__thiscallstd:

:

basic_string

:

char_traits,classstd:

:

allocator>:

:

basic_string

:

char_traits,classstd:

:

allocator>(charconst*)"(?

?

0?

$basic_string@DU?

$char_traits@D@std@@V?

$allocator@D@2@@std@@QAE@PBD@Z)alreadydefinedinmsvcprtd.lib(MSVCP80D.dll)

说在msvcprtd.lib和MSVCRTD.lib中已经定义过。

Crypto++使用经验总结

?

Crypto++使用经验总结

Crypto++是一套关于应用密码学的类库,提供了散列(MD5、SHA)、数据加密(DES、AES)、数字签名(RSA、椭圆曲线签名算法ECDSA)等很多有用的算法,算法安全性已经通过FIPS140-2(http:

//csrc.nist.gov/cryptval/140-2.htm)验证。

?

下面是一些使用中的总结:

?

一、将一个缓冲区编码

1.首先声明一个字符串来存放编码的结果

stringstr;

2.接着声明一个编码器(HexEncoder可替换为Base64Encoder等)对象,并通过StringSink类关联两者

HexEncoderencoder(newStringSink(str));

3.将数据放入编码器中

bytebuf[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

构造方法

AutoSeededRandomPoolrng;//随机数产生器

ECIES:

:

Decryptorcpriv(rng,ASN1:

:

sect193r1());//私钥,自己保留

ECIES:

:

Encryptorcpub(cpriv);//公钥,提供给用户

注意:

椭圆曲线加密算法是拥有公钥的人将数据加密后,密文发送给自己,自己来解密,所以不适用于注册码的生成

2.ECDSA

以下描述一个自定义的椭圆曲线的构造过程(以GF(p)上的椭圆曲线为例),参数可从以下网址得到http:

//www.cryptomathic.dk/labs/ellipticcurvedemo.html

//

Integermodulus("199999999999999999999999980586675243082581144187569");

//a、b为椭圆曲线参数

Integera("659942,b7261b,249174,c86bd5,e2a65b,45fe07,37d110h");

Integerb("3ece7d,09473d,666000,5baef5,d4e00e,30159d,2df49ah");

//计算基点G的两个参数x、y

Integerx("25dd61,4c0667,81abc0,fe6c84,fefaa3,858ca6,96d0e8h");

Integery("4e2477,05aab0,b3497f,d62b5e,78a531,446729,6c3fach");

Integerr("100000000000000000000000000000000000000000000000151");

Integerk

(2);

//私有密钥

Integerd("76572944925670636209790912427415155085360939712345");

?

//椭圆曲线

ECPec(modulus,a,b);

//P为基点G

ECP:

:

PointP(x,y);

//计算基点G

P=ec.Multiply(k,P);

//Q为公开密钥

ECP:

:

PointQ(ec.Multiply(d,P));

ECIES:

:

Decryptorcpriv(ec,P,r,d);

ECIES:

:

Encryptorcpub(cpriv);

ECDSA:

:

Signerspriv(cpriv);

ECDSA:

:

Verifierspub(spriv);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1