奇妙的安全旅行之DSA算法
hi,大家好,我是開發(fā)者FTD。今天我們來介紹一下非對(duì)稱加密算法中的DSA算法。
DSA 算法簡(jiǎn)介
DSA(Digital Signature Algorithm)是Schnorr和ElGamal簽名算法的變種,被美國(guó)NIST作為DSS(DigitalSignature Standard) 數(shù)字簽名的標(biāo)準(zhǔn)。
DSA是一種更高級(jí)的驗(yàn)證方式,它是一種公開密鑰算法,不能用來加密數(shù)據(jù),一般用于數(shù)字簽名和認(rèn)證。DSA 不單單只有公鑰、私鑰,還有數(shù)字簽名。私鑰加密生成數(shù)字簽名,公鑰驗(yàn)證數(shù)據(jù)及簽名。在DSA數(shù)字簽名和認(rèn)證中,發(fā)送者使用自己的私鑰對(duì)文件或消息進(jìn)行簽名,接受者收到消息后使用發(fā)送者的公鑰來驗(yàn)證簽名的真實(shí)性,包括數(shù)據(jù)的完整性以及數(shù)據(jù)發(fā)送者的身份。如果數(shù)據(jù)和簽名不匹配則認(rèn)為驗(yàn)證失敗!數(shù)字簽名的作用就是校驗(yàn)數(shù)據(jù)在傳輸過程中不被修改。
DSA數(shù)字簽名可以理解為是單向加密的升級(jí),不僅校驗(yàn)數(shù)據(jù)完整性,還校驗(yàn)發(fā)送者身份,同時(shí)還由于使用了非對(duì)稱的密鑰來保證密鑰的安全,所以相比消息摘要算法更安全。
DSA只是一種算法,和RSA不同之處在于它不能用作加密和解密,也不能進(jìn)行密鑰交換,只用于簽名,它比RSA要快很多。
DSA 算法簽名過程
DSA 算法原理
DSA是基于整數(shù)有限域離散對(duì)數(shù)難題的,其安全性與RSA相比差不多。DSA的一個(gè)重要特點(diǎn)是兩個(gè)素?cái)?shù)公開,這樣,當(dāng)使用別人的p和q時(shí),即使不知道私鑰,你也能確認(rèn)它們是否是隨機(jī)產(chǎn)生的,還是作了手腳。
DSA 算法參數(shù)定義
- p:一個(gè)素模數(shù),其值滿足:2^(L-1) < p < 2^L,其中L是64的倍數(shù),且滿足512≤ L ≤ 1024
- q:(p-1)的素因子,其值滿足2^159 < q < 2^160,即q長(zhǎng)度為160位。
- g:g = powm(h,(p-1)/q,p)。h為滿足1 < h < p-1 的任意整數(shù),從而有powm(h,(p-1)/q,p) > 1
- x:私鑰。x為一個(gè)隨機(jī)或偽隨機(jī)生成的整數(shù),其值滿足 0 < x < q。
- y:公鑰。y = powm(g,x,p)
注:
DSA 簽名過程:
注:
k^(-1) 表示整數(shù)k關(guān)于某個(gè)模數(shù)的逆元,并非指k的倒數(shù)。k在每次簽名時(shí)都要重新生成,用于不要將同樣的k用于進(jìn)行其他的簽名運(yùn)算!
- 逆元:滿足(a * b) mod m = 1 的a 和 b 互為關(guān)于模數(shù) m 的逆元,表示為 a = b^(-1) 或 b = a^(-1)。如(2 * 5) mod 3 = 1,則 2 和 5 互為模數(shù) 3 的逆元。
SHA(M): M 的 hash 值,M為待簽名的明文。SHA 是一個(gè)單向散列函數(shù)。DSS中選用SHA1算法,此時(shí)SHA(M) 為160 bits長(zhǎng)的數(shù)字串,其滿足不可逆和抗碰撞性。
最終的簽名就是證書對(duì)(r, s),它們和 M 一起發(fā)送到驗(yàn)證方。
盡管 r 和 s 為 0 的概率相當(dāng)小,但只要有任何一個(gè)為 0 ,必須重新生成 k,并重新計(jì)算 r 和 s 。
DSA 驗(yàn)證簽名過程:
我們用(r’, s’, M’) 來表示驗(yàn)證方通過某種途徑獲得的簽名結(jié)果,之所以這樣表示是因?yàn)槟悴荒鼙WC你這個(gè)簽名的結(jié)果一定是發(fā)送方生成的真簽名相反有可能被人篡改過,甚至掉了包。為了描述簡(jiǎn)便,下面仍用(r, s, M) 代替(r’, s’, M’)。
為了驗(yàn)證(r, s, M) 的簽名是否確由發(fā)送方所簽,驗(yàn)證方需要有(g, p, q, y),驗(yàn)證過程如下:
注:
DSA 算法實(shí)現(xiàn)
DSA密鑰生成:
public static Map<String, Object> initKey(String seed) throws Exception {KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);// 初始化隨機(jī)產(chǎn)生器 SecureRandom secureRandom = new SecureRandom();secureRandom.setSeed(seed.getBytes());keygen.initialize(1024, secureRandom);KeyPair keys = keygen.genKeyPair();PublicKey publicKey = keys.getPublic();PrivateKey privateKey = keys.getPrivate();Map<String, Object> map = new HashMap<String, Object>(2);map.put(PUBLIC_KEY, publicKey);map.put(PRIVATE_KEY, privateKey);return map; }用私鑰對(duì)信息生成數(shù)字簽名:
public static String sign(byte[] data, String privateKey) throws Exception {// 解密由base64編碼的私鑰 byte[] keyBytes = Base64.decodeBase64(privateKey);// 構(gòu)造PKCS8EncodedKeySpec對(duì)象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取私鑰匙對(duì)象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);// 用私鑰對(duì)信息生成數(shù)字簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(priKey);signature.update(data);return Base64.encodeBase64String(signature.sign()); }校驗(yàn)數(shù)字簽名:
public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {// 解密由base64編碼的公鑰 byte[] keyBytes = Base64.decodeBase64(publicKey);// 構(gòu)造X509EncodedKeySpec對(duì)象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取公鑰匙對(duì)象 PublicKey pubKey = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(pubKey);signature.update(data);// 驗(yàn)證簽名是否正常 return signature.verify(Base64.decodeBase64(sign)); }查看完整代碼請(qǐng)?jiān)L問:
https://github.com/ForTheDevelopers/JavaSecurity
總結(jié)
DSA 算法應(yīng)該屬于數(shù)字簽名屆的翹楚了,非對(duì)稱密鑰大大增強(qiáng)了算法的安全性,目前已經(jīng)被廣泛應(yīng)用到數(shù)字簽名領(lǐng)域。
創(chuàng)作不易,如果大家喜歡本文,歡迎點(diǎn)贊,轉(zhuǎn)發(fā),你的關(guān)注是我們繼續(xù)前進(jìn)的動(dòng)力_
com/ForTheDevelopers/JavaSecurity)
總結(jié)
DSA 算法應(yīng)該屬于數(shù)字簽名屆的翹楚了,非對(duì)稱密鑰大大增強(qiáng)了算法的安全性,目前已經(jīng)被廣泛應(yīng)用到數(shù)字簽名領(lǐng)域。
創(chuàng)作不易,如果大家喜歡本文,歡迎點(diǎn)贊,轉(zhuǎn)發(fā),你的關(guān)注是我們繼續(xù)前進(jìn)的動(dòng)力_
關(guān)于作者
-
GitHub:https://github.com/ForTheDevelopers
-
掘金:https://juejin.cn/user/1204720472953022/posts
-
CSDN:https://blog.csdn.net/ForTheDevelopers
-
segmentfault:https://segmentfault.com/u/for_the_developers
聯(lián)系作者
-
微信號(hào):ForTheDeveloper
-
公眾號(hào):ForTheDevelopers
總結(jié)
以上是生活随笔為你收集整理的奇妙的安全旅行之DSA算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中final是修饰符么_Java
- 下一篇: 信息摘要算法之三:SHA256算法分析与