关闭

Crypto++(二)数字签名算法DSA

标签: 密码学数字签名Crypto++
1259人阅读 评论(14) 收藏 举报
分类:

本文翻译自 https://www.cryptopp.com/wiki/Digital_Signature_Algorithm,本人英文水平有限,如有翻译不当之处请给出修改建议!

DSA是数字签名算法,DSA是 FIPS 186中指定的三种数字签名方案之一。FIPS 186-2 指定了一个1024位的p,160位的q,并且使用SHA-1作为哈希算法。FIPS 186-3 使用更大的哈希值SHA-2作为哈希算法,p值增大到3072位,q值增大到256位。FIPS 186-3 在2009年6月生效。

在早期的FIPS186文档中,为了允许更小的DSA模运算,未定义 DSA_1024_BIT_MODULUS_ONLY。如果要使用一个更低级别的模运算大小,一定要记住模数的PRIME_LENGTH_MULTIPLE倍 一定要介于 DSA::MIN_PRIME_LENGTH和 DSA::MAX_PRIME_LENGTH之间。

1. 构造函数

DSA::PublicKey 和 DSA::PrivateKey 都是由不接受任何参数的模板类定义的。详细的定义参看gfpcrypt.h头文件。

2 样例程序

2.1 密钥生成

下面的样例代码生成一个DSA密钥。

#include "dsa.h"
#include "osrng.h"

int main(int argc, char* argv[])
{
   AutoSeededRandomPool rng;

   // Generate Private Key
   DSA::PrivateKey privateKey;
   privateKey.GenerateRandomWithKeySize(rng, 1024);

   // Generate Public Key   
   DSA::PublicKey publicKey;
   publicKey.AssignFrom(PrivateKey);
   if (!privateKey.Validate(rng, 3) || !publicKey.Validate(rng, 3))
   {
      throw runtime_error("DSA key generation failed");
   }

   return 0;
}

2.2 加载和保存

下面的程序序列化DSA密钥为PKCS#8 和 X.509格式扩展了密钥生成样例, 在下面的代码中,编码后的密钥(encodedPublicKey 和 encodedPrivateKey)存在于内存中。密钥能够被持久化到磁盘中,使用FileSink 而是不 StringSink类。下面的代码使用StringSink和string来保存私钥。尽管方便,但是不是一个好的主意。

AutoSeededRandomPool rng;

// Generate Public and Private Keys
DSA::PrivateKey privateKey = ...; 
DSA::PublicKey publicKey = ...;
...

// DER Encoded Keys
string encodedPublicKey, encodedPrivateKey;

// Serialize in PKCS#8 and X.509 format
publicKey.Save( StringSink(encodedPublicKey).Ref() );
privateKey.Save( StringSink(encodedPrivateKey).Ref() );

// Decode DSA keys
DSA::PrivateKey decodedPrivateKey;
decodedPrivateKey.Load(
   StringStore(encodedPrivateKey).Ref()
);

DSA::PublicKey decodedPublicKey;
decodedPublicKey.Load(
  StringStore(encodedPublicKey).Ref()
);

2.3 签名生成和验证

建立在之前例子的基础上,接下来的例子签名并验证一个消息。签名使用SignerFilter完成,而验证是由SignatureVerificationFilter类完成的。

// Generate or Load the Public and Private Keys
DSA::PrivateKey PrivateKey; 
DSA::PublicKey PublicKey;
...

string message = "DSA Signature";
string signature;

DSA::Signer signer( PrivateKey );
StringSource ss1( message, true, 
    new SignerFilter( rng, signer,
        new StringSink( signature )
    ) // SignerFilter
); // StringSource

DSA::Verifier verifier( PublicKey );
StringSource ss2( message+signature, true,
    new SignatureVerificationFilter(
        verifier, NULL, THROW_EXCEPTION
        /* SIGNATURE_AT_END */
    )
);

cout << "Verified signature on message" << endl;

在上述的例子中,过滤器接受message+signature的串联,如果签名首先被插入,SIGNATURE_AT_BEGIN 应该被指定为一个额外的标签值。


DSA::Verifier verifier( PublicKey );
StringSource ss( signature+message, true,
    new SignatureVerificationFilter(
        verifier, NULL,
        THROW_EXCEPTION | SIGNATURE_AT_BEGIN
    )
);

接下来的样例验证签名而不抛出异常。该样例使用标签 PUT_RESULT。 SignatureVerificationFilter 将会把结果添加到附加的转换中。结果通过管道输入bool值result。为了方便管道(传输数据)变量被包装成ArraySink。以下代码中有三点值得关注:首先,同时指定PUT_RESULT 和 THROW_EXCEPTION没有任何意义;其次,StringSink不能够被使用因为为bool值不是继承自std::basic_string;最后,唯一的标签是PUT_RESULT,因此签名必须在最后呈现(SIGNATURE_AT_BEGIN没有被指定)。

...

DSA::Verifier verifier( PublicKey );

bool result = false;
StringSource ss( message+signature, true,
    new SignatureVerificationFilter(
        verifier,
        new ArraySink(
            (byte*)&result, sizeof(result ) ),
        PUT_RESULT | SIGNATURE_AT_END
    )
);

if( true == result ) {
    cout << "Verified signature on message" << endl;
}

最后的代码使用一个鲜为人知的sink称为转向器。并不拥有其附加的BufferedTransformation转向器,所以附加对象没有被删除(行为的结果,转向器需要引用而不是指针)。那是有用的, 当需要一个中间结果,该结果从一个对象。

...

DSA::Verifier verifier( PublicKey );
SignatureVerificationFilter svf(
    verifier /* SIGNATURE_AT_END */
); // SignatureVerificationFilter

StringSource ss( message+signature, true,
    new Redirector( svf )
); // StringSource

if( true == svf.GetLastResult() ) {
    cout << "Verified signature on message" << endl;
}
5
0
查看评论

CryptoAPI加解密签名验证

  • 2018-01-14 19:08
  • 11.48MB
  • 下载

Crypto库实现PKCS7签名与签名验证

在windows中,可以直接使用微软提供的crypto库实现PKCS7签名与签名验证。签名接口函数为CryptSignMessage,其接口定义为: BOOL WINAPI CryptSignMessage( __in PCRYPT_SIGN_MESSAGE_PARA pSi...
  • wangsifu2009
  • wangsifu2009
  • 2012-05-12 16:19
  • 5291

使用crypto api的签名和验证签名源代码

使用crypto api的签名和验证签名源代码 #include "stdafx.h" //-------------------------------------------------------------------- // 数字签名以及认证 #include ...
  • hepfei90
  • hepfei90
  • 2013-11-20 20:41
  • 1271

数字签名和验签

什么是对称加密和非对称加密? 对称加密是指:有一个密钥,加密用它来加密,解密也需要用到它。因为加密解密都是用同一个密钥所以叫对称加密。 非对称加密是指:就是有 2 个密钥,一个是公钥,一个是私钥。私钥是自己的,不能随便给人,公钥随便给,无所谓。一般是别人用你的公钥加密,然后把密文给你,你用你的私...
  • sunboy2718
  • sunboy2718
  • 2014-08-06 10:56
  • 689

Crypto++学习总结--算法介绍

Crypto++  算法介绍         Crypto++是开源的C++数据加密算法库,支持如下算法:RSA、MD5、DES、AES、SHA-256等等。对于加密有对称加密和非对称加密。   对称加密:采用单钥密码系统的加密...
  • wangweitingaabbcc
  • wangweitingaabbcc
  • 2013-09-05 15:54
  • 4374

C++利用Crypto++,vs2005环境下的RSA应用

固定生成随机密钥,存储和装载。解决加密时字符串长度问题
  • Yo_Joky
  • Yo_Joky
  • 2015-07-24 15:02
  • 610

基于Crypto++/Cryptopp的rsa密钥生成,rsa加密、解密,rsa签名、验签

转载于http://www.xdty.org/1678 在项目中需要增加一个注册的功能,想到了用rsa非对称加密的方法。对比了openssl等第三方库,最后采用了Cryptopp。 1.源文件整理 可以在http://www.cryptopp.com/获取库的源文件,解压后将文件重新归...
  • u011676589
  • u011676589
  • 2015-01-29 10:44
  • 1225

RSA加密及验证签名

首先创建密钥工具类 import java.security.Key;   import java.security.KeyFactory;   import java.security.KeyPair;   import java.security.KeyPa...
  • guishengbin
  • guishengbin
  • 2016-07-15 13:04
  • 1230

.NET中的安全性之数字签名、数字证书、强签名程序集、反编译

本文将探讨数字签名、数字证书、强签名程序集、反编译等以及它们在.NET中的运用(一些概念并不局限于.NET在其它技术、平台中也存在)。 1.数字签名 数字签名又称为公钥数字签名,或者电子签章等,它借助公钥加密技术实现。数字签名技术主要涉及公钥、私钥、非对称加密算法。 1.1公钥与私钥 公钥是...
  • hezudao25
  • hezudao25
  • 2012-03-08 11:47
  • 2440

数字签名算法DSA

一、概述 1、DSA是以RSA为基础形成的 2、java6提供了DSA的实现,但是java6只提供了SHA1withDSA的实现 3、bouncycastle扩展提供了其他的DSA实现方式 4、遵循“私钥签名,公钥验证”的原则 二、模型分析 这个和RSA一样,只是...
  • bravegogo
  • bravegogo
  • 2016-12-28 20:41
  • 1663
    机器学习公众号

    关注微信公众号,专

    为机器学习入门者
    个人资料
    • 访问:228446次
    • 积分:4739
    • 等级:
    • 排名:第7252名
    • 原创:115篇
    • 转载:14篇
    • 译文:3篇
    • 评论:787条
    博客专栏
    最新评论