crypto++ User Guide: filters.h学习笔记

来源:互联网 发布:ci 数据库配置 编辑:程序博客网 时间:2024/06/07 11:42

感觉程序员学密码学不把一个库玩的很6是学不好也用不了密码学的,对crypto++而言,看源码

暂时是看不懂也看不完的,只能硬着头皮看官方文档,本人英文不是很好,如有错误请直接指出。

Base Classes

Filter

译文start

Filter是一个抽象基础类继承自BufferedTransformation.它的公共接口和他的父类相同;

但是它实现了 attachment 功能。在BufferedTransformation中 attachment 只是声明但是没有实现

译文end

学习笔记

这里出现了一个名词 抽象类,找了篇文章http://www.cnblogs.com/dongsheng/p/3343939.html

说说 抽象类 的要点吧

  1. 包含纯虚函数的类称为抽象类

  2. 不能定义抽象类的对象(个人猜测和虚表有关)

  3. 存在的意义是被继承

在filter类中这个只定义没有实现的虚函数就是virtual BufferedTransformation * NewDefaultAttachment() const;

//这里代码不全,只粘要点class CRYPTOPP_DLL CRYPTO_NO_VTABLE Fileter:BufferedTransformation,public NotCapyable{    Filter(BufferedTransformation *attachment = NULL);    bool Attachable() {return true;}        BufferedTransformation *AttachedTransformation();    const BufferedTransformation *AttachedTransformation() const;    void Detach(BufferedTransformation *newAttachment = NULL);protected:    virtual BufferedTransformation * NewDefaultAttachment() const;}

译文start

有个可行的方法来区分一个Filter和BufferedTransformation对象通过调用Attachable()方法

如果对象是一个Filter,方法将会返回true,如果是BufferedTransformation则返回false

(注:通过定义新类继承Filter和BufferedTransformation,译者测试的确如此,这里不就贴代码了,

vs神器不是吹的)

Attachment(译成 附着)是一个先进并且实用的概念,通过filters和它们的依赖功能,可以用相关的少量代码

优雅的实现很多东西

当一个继承自BufferedTransformation的对象B,附着于一个继承自Filter的对象F,当数据通过Put()方法发送到F,

F将处理数据,然后通过B的Put()函数把结果转发到B. 当F调用任何的Get()方法,F将简单的转发到B,并返回B的返回值.

如果B是其他继承自Filter的对象,它也会同样如此,这形成一个附着链,这个附着链一定以一个

BufferedTransformation结束,而不是Filter.

(注:在Filter中没有实现Put() 和 Get(),BufferedTransformation实现了Put() 和 Get())

这非常简单. 而且很神奇!看例子

char const* zInputFile=...;char const* zOutputFile=...;SHA hash;FileSource(zInputFile,true,new HashFilter(hash,new FileSink(zOutputFile),true));

上述代码通过FileSouce打开被zInputFile指定的文件,通过HashFilter把该文件传送给SHA hash模块,并且通过

FileSink存储原来的数据和计算得到的摘要到zOutpuFile指定的文件中(译注:该文件为新建文件),如果在最后一行的

true 参数被省略掉,缺省的false将会应用,那么输出文件不会保存原来数据,只会有原来数据的消息摘要

译文end

附着方法(Attachment methods)

译文start

构造函数.所有从继承自Filter的类和Filter类本身,都有一个BufferedTransformation*类型的参数

这个参数指定了一个指针,这个指针指向一个继承自BufferedTransformation对象,这个对象附着于(attach)

那个即将由构造函数构造的对象.

一旦附着关系开始,附着目标对象拥有指向被用来附着的对象指针,一旦附着目标对象被摧毁,

被用作附着的对象会自动被释放.

当调用构造函数时,如果被用来附着的对象没有被指定或者传递了一个空指针,那么一个预先确定的对象会被创建

一般来说,会创建一个MessageQueue对象.一个MessageQueue对象将会储存所有它从Put()方法获取的数据,这些

数据之后可以通过Get()方法获得,它Put()方法和Get()方法所获取的数据的顺序相同。

Attach().附着另外一个transformation对象到 附着链 的尾部

Detach().删除当前的附着链,摧毁并且释放它包含的所有对象,然后附着指定的对象,如果传递的是个空指针,

那就创建一个默认对象

AttachedTransformation().返回一个指向当前被用作附着的对象,不能是NULL

     // 和之前那个例子类似,但是没有使用sink      // HashFilter创建一个MessageQueue附着对象      // 通过Get()提取消息摘要      char const* zInputFile = ...;      char const* zOutputFile = ...;      SHA hash;      FileSource source(zInputFile, true, new HashFilter(hash));      byte abDigest[SHA::DIGESTSIZE];      if (source.Get(abDigest, sizeof(abDigest)) != sizeof(abDigest))          throw "shouldn't happen";

使用Deatach()和Attach()

  // 在对象创建时期,不抽取(pump)任何东西,而不是立即抽取(pump)整个文件(在FileSource中使用false参数,  // 而不是之前的true)  string sEncoding;  FileSource source(zInputFile, false, new StringSink(sEncoding));  //source.Pump(3);这句译者者测试时报错(vs2017 & win10)  // 再附着上FileSink, 最后写入文件  // 写入的文件应该是16进制或者base64encode  source.Detach(new HexEncoder);  source.Attach(new FileSink(zOutputFile));  source.PumpAll();

译文end

Sink

译文start

不像Source,Sink抽象基础类继承自BufferedTransformation.在一个filters**附着链**中,sink

总是在链中的最后一个对象:

示例:将一个文件中的内容读取到一个字符串中

char const* zInputFile="temp.txt";string content;FileSource source(zInputFile,true,new StringSink(content));cout<<content;

(译者注:继承关系:FileSink->Sink->BufferdTransformation,FileSource->Source->Filter)

示例:把哈希值存入一段缓存区中

    string sData="Hello CryptoPP";    byte abDigest[SHA::DIGESTSIZE];    SHA sha;    StringSource source(sData,true,        new HashFilter(sha,            new ArraySink(abDigest,sizeof(abDigest))));

(译注:继承关系:StringSource->Source->Filter,ArraySink->Sink->BufferedTransformation)

译文end

派生类

MeterFilter,TransparentFilter,OpaqueFilter

StreamCiherFilter

HashFilter,HashVerifier

(译注:HashFilter->Filter)

HashFilter被消息摘要算法初始化,HashFilter使用这个算法来计算素所有输入数据的哈希值,直到第一个

MessageEnd()信号,当它遇到MessageEnd()信号时,它把计算所得的哈希值输出到它的附着transformation

HashFilter会根据初始化参数决定在输出哈希值前是否把数据输入到附着transformation.

一旦 MessageEnd(), 被指向这个消息摘要就被重置并且可以处理另外一条消息.

HashVerifier是一个灵活的filter,它处于验证输入消息的摘要的目的封装一个消息摘要算法.

有很多标志可以被设置在HashVerifier初始化的时候,这依赖于哈希值将会被装载到哪(消息的起始还是结束),

无论消息,依赖于消息和哈希值是否会被传送到附着transformation,依赖于验证结果是否被传送到,附着transformaiton

以及异常是否会排除如果摘要验证失败。

 char const* zInputFile = ...; char const* zOutputFile = ...; SHA hash; FileSource(zInputFile, true,     new HashFilter(hash,         new FileSink(zOutputFile),         true)); // The last 'true' parameter means that the whole message // will be forwarded to FileSink, not just the calculated hash. // If omitted, the default value would be 'false'.

SignerFilter,VerifierFilter

SignerFilter一般而言是一个基本类,它封装一个PK_Signer派生类来应用一个数字签名到输入数据,

只有数字签名被传送到附着transformation.

Verifier一般而言也是一个基础类封装一个PK_Signer派生类来验证一个输入数据的数字签名,这个数字签名背身必须

通过PutSignature()方法传送给VerifierFilter对象

在实际中,在PK_Signer和PK_Verifier对象上分别使用SignMessage()和VerifyMessage()方法

通常更简单

AutoSeededRandomPool rng; // The below type is derived from PK_Signer RSASSA_PKCS1v15_SHA_Signer privkey = ...; char const* zInputFile = ...; string sSignature; FileSource(zInputFile, true,     new SignerFilter(rng, privkey,         new StringSink(sSignature))); // sSignature now contains the digital signature computed on the // contents of the input file using SHA and RSA

Redirector

Redirector是一个Sink,它在附着链的末尾,但是传递输入数据到另外一条附着链,使用Redirector和使用普通的附着

之间的不同是Redirector并不游泳它的附着transformatuion,它不会摧毁并能切释放附着对象一旦它被摧毁

示例:连接文件

 void ConcatenateFiles(BufferedTransformation& bt)  {      char const* zInputFile1 = ...;      char const* zInputFile2 = ...;      char const* zInputFile3 = ...;      // Concatenate the three files into the same BufferedTransformation object.      // Only allow the MessageEnd() signal to be passed into bt at the end      // of the last file.      FileSource(zInputFile1, true, new Redirector(bt, false));      FileSource(zInputFile2, true, new Redirector(bt, false));      FileSource(zInputFile3, true, new Redirector(bt));  }  ...  string sConcatenated;  ConcatenateFiles(StringSink(sConcatenated));

ArraySink

ArraySink是一个用来把数据存进一个预先定好大小的缓存区;已经存储的字节数和还能使用的空间可以通过

AvailableSize()方法和TotalPutlength()确定.

示例:将一个哈希值存入一段缓存区

 string sData = ...; byte abDigest[SHA::DIGESTSIZE]; SHA sha; StringSource(sData, true,     new HashFilter(sha,         new ArraySink(abDigest, sizeof(abDigest))));

StringSinkTemplate,StringSink

StringSinkTemplate是一个Sink模板,它把数据存储到任何派生自std::basic_string的string类型

StringSink是一个 StringSinkTemplate的typedef

当StirngSink使用一个非空目标字符串初始化,目标字符串会被添加上去;原先的内容保持不变

StringSource

StringSource是一个Source,它从一个Ascii字符串或者一个字符串缓存区中提取字符串