注意:只是我的理解,可能有不正確的地方git
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 google
DSA算法是ElGamal算法的一個變種。ElGamal算法參見:http://my.oschina.net/u/1382972/blog/330630 加密
公鑰、私鑰生成:spa
分爲兩部分,首先約定算法的一些參數,而後爲各個用戶生成公私鑰。
.net
算法參數:orm
一、選定一個哈希函數H,最初爲SHA-1,如今SHA-2也能夠使用。函數輸出有可能須要截短到密鑰對的長度。blog
二、選定密鑰的長度L、N。密鑰長度決定了加密可靠度。最近的標準FIPS 186-3指定長度應該爲:(1024,160), (2048,224), (2048,256), and (3072,256)遊戲
三、選取N位長度的一個質數q。N長度必須小於或等於哈希函數H輸出長度。
四、選取L位長度的一個質數p,並知足(p-1)%q=0。
五、選取一個整數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)構成公用的算法參數。
公、私鑰生成:
一、選取任意整數x, 0 < x < q
二、計算 y = g^x%p
三、公鑰爲(p, q, g, y),私鑰爲x
生成簽名:
一、生成隨機數k,0 < k < q
二、計算r = g^k%p%q,若是r=0,從新選取k
三、計算s=(H(m)-x*r)*(k^(-1))%q,H爲哈希函數,m爲待簽名數據,若是s=0,從新選取k
四、(r, s)構成簽名
驗證簽名:
一、驗證:0<r<q,0<s<q
二、計算w = (s^(-1))%q
三、計算u1 = H(m)*w%q
四、計算u2 = r*w%q
五、計算v = (((g^u1)*(y^u2))%p)%q
六、若是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