注意:只是个人理解,可能有不正确的地方
DSA(Digital Signature Algorithm)签名算法是由美国国家标准与技术研究院(NIST, National Institute of Standards and Technology)提出的一个关于数字签名的美国联邦信息处理标准(FIPS, Federal Information Processing Standard)。该标准在1991年8月提出,1993以FIPS 186被采用,作为数字签名(DSS, Digital Signature Standard)的一部分。
DSA受5,231,668号美国专利(U.S. Patent 5,231,668)保护,该专利在1991年7月提交,发明人为David W. Kravitz,当时为美国国安局(NSA, National Security Agency)雇员。专利受让人为由美国商务部书记处(United States Secretary of Commerce is head of United States Department of Commerce)为其代表的美国政府。后来美国国家标准与技术研究院免除了该专利授权费,向全世界提供。
专利原文:https://www.google.com/patents/US5231668
DSA算法是ElGamal算法的一个变种。ElGamal算法参见:http://my.oschina.net/u/1382972/blog/330630
公钥、私钥生成:
分为两部分,首先约定算法的一些参数,然后为各个用户生成公私钥。
算法参数:
1、选定一个哈希函数H,最初为SHA-1,现在SHA-2也可以使用。函数输出有可能需要截短到密钥对的长度。
2、选定密钥的长度L、N。密钥长度决定了加密可靠度。最近的标准FIPS 186-3指定长度应该为:(1024,160), (2048,224), (2048,256), and (3072,256)
3、选取N位长度的一个质数q。N长度必须小于或等于哈希函数H输出长度。
4、选取L位长度的一个质数p,并满足(p-1)%q=0。
5、选取一个整数g,g是满足等式q^g%p=1的最小整数。g可以用公式g = h^((p–1)/q)%p得到,h为任意整数,只要1 < h < p?1,h通常选为2,但如果g的结果为1时,需要再选一个其它数。
(p, q, g)构成公用的算法参数。
公、私钥生成:
1、选取任意整数x, 0 < x < q
2、计算 y = g^x%p
3、公钥为(p, q, g, y),私钥为x
生成签名:
1、生成随机数k,0 < k < q
2、计算r = g^k%p%q,如果r=0,重新选取k
3、计算s=(H(m)-x*r)*(k^(-1))%q,H为哈希函数,m为待签名数据,如果s=0,重新选取k
4、(r, s)构成签名
验证签名:
1、验证:0<r<q,0<s<q
2、计算w = (s^(-1))%q
3、计算u1 = H(m)*w%q
4、计算u2 = r*w%q
5、计算v = (((g^u1)*(y^u2))%p)%q
6、如果v=r则签名有效。
随机数k的选取很重要,如果不够随机,或者即使其中几位为泄露,也足够使DSA被攻破。
2010年索尼公司为其游戏主机PS3签发软件使用的ECDSA签名的私钥被破解。原因就是没有为每个签名使用不同的随机数k。ECDSA是结合椭圆曲线(EC, Elliptic curve)特定和DSA算法的一种签名算法。
RFC 6979文件描述了一种使用私钥x和H(m)计算得出k的方法,来避免上述问题,使每个签名的k不相同,且无法被破解者估计出。
参考:
DSA算法: http://en.wikipedia.org/wiki/Digital_Signature_Algorithm