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

本文详细介绍了Crypto++库中的Filter模型,包括其继承关系、构造方法、附着机制等,并通过具体示例展示了如何使用Filter进行消息摘要计算、数字签名等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感觉程序员学密码学不把一个库玩的很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字符串或者一个字符串缓存区中提取字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值