数字签名全攻略

论坛 期权论坛 期权     
信息安全club   2020-3-28 02:15   3214   0

数字签名原理



数字签名用技术手段在计算机世界中进行实现了现实世界中签字的功能,用于识别篡改和伪装并防止抵赖。


生成消息签名的人是由消息发送者。对消息签名就是根据消息内容计算数字签名的值。
在非对称密码学中,接收者的公钥用来加密,私钥用来解密。



而在数字签名中,发送者的私钥用来加密(生成签名),公钥用来验证签名。




生成和验证数字签名的方法有两种:
  • 直接对消息签名的方法


[h2]
[/h2]
  • 对消息的散列值签名的方法


通常我们会使用第 2 种方法。原因是非对称加密相对于对称加密非常耗时。利用简短的单向散列函数来替代消息本身再进行加密(对消息进行签名),会快很多。


为什么用私钥加密具备签名的意义?数字签名是利用了 “没有私钥的人就无法生成使用该私钥所生成的密文” 这一性质来实现的。生成的密文代表一种只有持有该密钥的人才能生成的信息。所以私钥产生的密文是一种认证符号(authenticator)。


消息没有加密就直接发送,怎么保证消息的机密性?数字签名只保证消息的完整性和不可抵赖性,并不保证消息的机密性。如果需要保证机密性,可以考虑加密和数字签名结合起来使用。


签名可以随意复制么?数字签名代表的意义是特定的签名者与特定的消息绑定在一起,数字签名虽然可以任意复制,但是它只对特定的消息有意义。提取出签名,组合任意消息和该签名,并不能达到伪造消息的目的。验证者验证的时候会发现消息和签名的散列值不同,验证失败从而丢弃这条消息。



数字签名的应用场景
[h2]安全信息公告[/h2]信息安全组织会在网站上发布一些关于安全漏洞的警告。由于这些信息需要被更多的人知道,所以没有必要对消息进行加密。但是需要防止有人伪装该组织发布虚假信息,这个时候只需要加上数字签名即可。这种对明文消息所施加的签名,一般称为明文签名(clearsign)。


[h2]软件下载[/h2]为了保证下载软件的安全,不是恶意的病毒,软件作者会对软件加上数字签名。用户在下载完成以后,验证数字签名就能识别出下载的是不是被篡改过的软件。


[h2]公钥证书[/h2]验证数字签名的时候需要合法的公钥,但是如何才能知道自己拿到的公钥是合法的呢?这个时候就需要把公钥作为信息,对它加上数字签名,得到公钥证书。关于证书的问题再下一篇文章里面详细分析。
[h2]
[/h2]SSL/TLS
在认证服务器身份的时候会使用服务器证书,服务器证书就是加上了数字签名的服务器公钥。
[h1]
[/h1]
算法签名



[h2]用 RSA 生成签名[/h2]签名 = 消息^D mod N

D 和 N 就是签名者的私钥。签名就是对消息的 D 次方求 mod N 的结果。


[h2]用 RSA 验证签名[/h2]消息 = 签名^E mod N

E 和 N 就是签名者的公钥。
[h2]
[/h2]DSA(Digital Signature Algorithm)
NIST(National Institute of Standards and Technology)于 1991 年制定的数字签名规范(Digital Signature Standard,DSS)。DSA 是 Schnorr 算法和 ElGamal 方式的变体,只能用于数字签名,不能进行加密解密。


DSA算法中应用了下述参数:
p:L 比特长的素数。L 是 64 的倍数,范围是 512 到 1024;
q:p – 1 的 160 比特的素因子;
g:g = h^((p-1)/q) mod p,h 满足 h < p – 1, h^((p-1)/q) mod p > 1;
x:x < q,x 为私钥;
y:y = g^x mod p ,( p, q, g, y )为公钥;
H( x ):单向Hash函数。DSS 中 选用 SHA( Secure Hash Algorithm )。
[h2]
[/h2][h2]生成 DSA 密钥对[/h2]
  • 选取一个随机数作为私钥 x ,0 < x < q。
  • 基于私钥生成公钥,g^x mod p

[h2]签名生成[/h2]
  • 生成一个随机数 k,1 < k < q。
  • 计算 r = (g^k mod p) mod q。
  • 计算 s = (k^(-1)(H(m)+xr)) mod q,
  • 签名值就是(r,s),随同原始消息 m 一起发送。
[h2]签名验证[/h2]
  • 假如 r 和 s 大于 q 或者小于 0,则验证直接失败
  • 计算 w = s^(-1) mod q
  • 计算 u1 = H(m).w mod q
  • 计算 u2 = r.w mod q
  • 计算 v = (g^u1 * y^u2 mod p) mod q
  • 如果 v 等于 r,则签名验证成功,否则失败


[h2]ECDSA(Elliptic Curve Digital Signature Algorithm)[/h2]是一种利用椭圆曲线密码来实现的数字签名算法。就像 DH 算法结合 ECC 一样,DSA 算法也能结合 ECC,称为 ECDSA 数字签名算法。相比 DSA 算法,ECDSA 算法安全性更高。
在 ECDSA 中,有三个参数很重要:
  • ECDSA 算法选择的命名曲线。
  • G,椭圆曲线的基点
  • n,相当于 G 基点的打点操作,n * G = 0
[h2]生成 ECDSA 密钥对[/h2]
  • 选择一个随机数作为私钥 d_{a},1< d_{a} < n -1
  • 基于私钥生成公钥,Q_{a} = d_{a} * G
[h2]签名生成[/h2]
  • 计算摘要值 e = HASH(m)
  • 获取 z = e 最左边的 L_{n} 位字符,L_{n} 是 n 的长度
  • 生成一个随机数 k,1 < k < n - 1
  • 计算 (x,y) = k * G
  • 计算 r = x mod n
  • 计算 s = k_{-1} (z + r * d_{-1}) mod n
  • 签名值(r,s)
[h2]验证签名[/h2]
  • 假如 r 和 s 小于 1 或者大于 n-1,验证直接失败
  • 获取 z = e 最左边的 L_{n} 位字符
  • 计算 w = s^{-1} mod n
  • 计算 u_{1} = zw mod n
  • 计算 u_{2} = rw mod n
  • 计算 (x,y) = u_{1} * G + u_{2} * Q_{a}
  • 如果 r == x_{1} mod n,则签名验证成功,否则失败


[h2]Rabin 方式[/h2]Rabin 方式是由 M.O.Rabin 设计的公钥算法,利用了在 mod N 中求平方根的困难度。Rabin 方式可以被用于公钥密码和数字签名。
[h1]
[/h1]
OpenSSL 中的 RSA 数字签名
数字签名技术需要涉及到摘要计算,所以需要指定 一个 Hash 算法。下面这个例子用 sha256 。


// 生成一个 RSA 密钥对,密钥长度 1024 长度
$ openssl genrsa -out rsaprivatekey.pem 1024

// 从密钥对中分离出公钥
$ openssl rsa -in rsaprivatekey.pem -pubout -out rsapublickey.pem

// 对 plain.txt 应用 sha256和签名算法生成签名文件 signature.txt
$ echo "hello" >> plain.txt
$ openssl dgst -sha256 -sign rsaprivatekey.pem -out signature.txt plain.txt

// 用相同的摘要算法和签名算法校验签名文件,需要对比签名文件和原始文件
$ openssl dgst -sha256 -verify rsapublickey.pem -signature signature.txt plain.txt

Verified OK

// 更换一个 txt 文件再次验证签名
$ openssl dgst -sha256 -verify rsapublickey.pem -signature signature.txt signature.txt

Verification Failure
[h1]
[/h1][h1]OpenSSL 中的 DSA 数字签名[/h1]// 生成参数文件,类似于 DH 参数文件
$ openssl dsaparam -out dsaparam.pem 1024
// 通过参数文件生成密钥对 dsaprivatekey.pem
$ openssl gendsa -out dsaprivatekey.pem dsaparam.pem
// 对私钥对文件使用 des3 算法进行加密
$ openssl gendsa -out dsaprivatekey2.pem -des3 dsaparam.pem
// 通过密钥对文件拆分出公钥
$ openssl dsa -in dsaprivatekey.pem -pubout -out dsapublickey.pem

// 查看三个公共参数、公钥、私钥
$ openssl dsa -in dsaprivatekey.pem -text
输出中的priv 和 pub 相当于密钥对中的私钥和公钥,P、Q、G 都是参数文件中的三个关键参数,这是 DSA 算法的关键。既然可以查看私钥文件的信息,同理可以查看公钥文件的信息。

// 查看公钥和文件的信息
$ openssl dsa -pubin -in dsapublickey.pem -text
输出的内容中,pub、P、Q、G 四个参数和私钥输出的内容是一致的。最后验证 DSA 签名算法。这里和 RSA 是差不多的

// DSA 进行签名
$ openssl dgst -sha256 -sign dsaprivatekey.pem -out signature.txt plain.txt

// 验证签名
$ openssl dgst -sha256 -verify dsapublickey.pem -signature signature.txt plain.txt

[h1]OpenSSL 中的 ECDSA 数字签名[/h1]
// 直接生成 ECDSA 私钥,不用预先生成 ECC 参数文件
$ openssl ecparam -name secp256k1 -genkey -out ecdsa_priv.pem

// 显示私钥信息
$ openssl ec -in ecdsa_priv.pem -text -noout
从输出可以看到私钥信息和命名曲线的信息,密钥长度是 256 比特。

// 提取公钥
$ openssl ec -in ecdsa_priv.pem -pubout -out ecdsa_pub.pem

// 显示公钥
$ openssl ec -in ecdsa_pub.pem -pubin -text -noout

// 选择 sha256 作为 HASH 算法
$ openssl dgst -sha256 -sign ecdsa_priv.pem -out signature.txt plain.txt


// 校验签名
$ openssl dgst -sha256 -verify ecdsa_pub.pem -signature signature.txt plain.txt

DSA 签名算法运算比 RSA 签名运算慢很多,但是 ECDSA 签名算法比 RSA 签名生成快的多,ECDSA 签名验证却比 RSA 签名验证相对慢一些。
从安全和速度综合考虑,在 DSA 和 ECDSA 中选一个,优先选择 ECDSA。


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:5
帖子:1
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP