日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

奇妙的安全旅行之DSA算法

發布時間:2024/7/23 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 奇妙的安全旅行之DSA算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

hi,大家好,我是開發者FTD。今天我們來介紹一下非對稱加密算法中的DSA算法。

DSA 算法簡介

DSA(Digital Signature Algorithm)是Schnorr和ElGamal簽名算法的變種,被美國NIST作為DSS(DigitalSignature Standard) 數字簽名的標準。

DSA是一種更高級的驗證方式,它是一種公開密鑰算法,不能用來加密數據,一般用于數字簽名和認證。DSA 不單單只有公鑰、私鑰,還有數字簽名。私鑰加密生成數字簽名,公鑰驗證數據及簽名。在DSA數字簽名和認證中,發送者使用自己的私鑰對文件或消息進行簽名,接受者收到消息后使用發送者的公鑰來驗證簽名的真實性,包括數據的完整性以及數據發送者的身份。如果數據和簽名不匹配則認為驗證失敗!數字簽名的作用就是校驗數據在傳輸過程中不被修改。

DSA數字簽名可以理解為是單向加密的升級,不僅校驗數據完整性,還校驗發送者身份,同時還由于使用了非對稱的密鑰來保證密鑰的安全,所以相比消息摘要算法更安全。

DSA只是一種算法,和RSA不同之處在于它不能用作加密和解密,也不能進行密鑰交換,只用于簽名,它比RSA要快很多。

DSA 算法簽名過程

  • 使用消息摘要算法將要發送數據加密生成信息摘要。
  • 發送方用自己的DSA私鑰對信息摘要再加密,形成數字簽名。
  • 將原報文和加密后的數字簽名一并通過互聯網傳給接收方。
  • 接收方用發送方的公鑰對數字簽名進行解密,同時對收到的數據用消息摘要算法產生同一信息摘要。
  • 將解密后的信息摘要和收到的數據在接收方重新加密產生的摘要進行比對校驗,如果兩者一致,則說明在傳送過程中信息沒有破壞和篡改;否則,則說明信息已經失去安全性和保密性。
  • DSA 算法原理

    DSA是基于整數有限域離散對數難題的,其安全性與RSA相比差不多。DSA的一個重要特點是兩個素數公開,這樣,當使用別人的p和q時,即使不知道私鑰,你也能確認它們是否是隨機產生的,還是作了手腳。

    DSA 算法參數定義
    • p:一個素模數,其值滿足:2^(L-1) < p < 2^L,其中L是64的倍數,且滿足512≤ L ≤ 1024
    • q:(p-1)的素因子,其值滿足2^159 < q < 2^160,即q長度為160位。
    • g:g = powm(h,(p-1)/q,p)。h為滿足1 < h < p-1 的任意整數,從而有powm(h,(p-1)/q,p) > 1
    • x:私鑰。x為一個隨機或偽隨機生成的整數,其值滿足 0 < x < q。
    • y:公鑰。y = powm(g,x,p)

    注:

  • 整數p,q,g可以公開,也可以僅由一組特定用戶共享。
  • 私鑰x和公鑰y稱為一個密鑰對(x,y),私鑰只能由簽名者本人獨自持有,公鑰則可以公開發布。密鑰對可以在一段時間內持續使用。
  • DSA 簽名過程:
  • 產生一個隨機數k,其值滿足 0 < k < q
  • 計算r = powm(g,k,p) mod q,其值滿足 r > 0
  • 計算 s = (k^(-1)(SHA(M) + x * r)) mod q,其值滿足 s > 0
  • 注:

  • k^(-1) 表示整數k關于某個模數的逆元,并非指k的倒數。k在每次簽名時都要重新生成,用于不要將同樣的k用于進行其他的簽名運算!

    • 逆元:滿足(a * b) mod m = 1 的a 和 b 互為關于模數 m 的逆元,表示為 a = b^(-1) 或 b = a^(-1)。如(2 * 5) mod 3 = 1,則 2 和 5 互為模數 3 的逆元。
  • SHA(M): M 的 hash 值,M為待簽名的明文。SHA 是一個單向散列函數。DSS中選用SHA1算法,此時SHA(M) 為160 bits長的數字串,其滿足不可逆和抗碰撞性。

  • 最終的簽名就是證書對(r, s),它們和 M 一起發送到驗證方。

  • 盡管 r 和 s 為 0 的概率相當小,但只要有任何一個為 0 ,必須重新生成 k,并重新計算 r 和 s 。

  • DSA 驗證簽名過程:

    我們用(r’, s’, M’) 來表示驗證方通過某種途徑獲得的簽名結果,之所以這樣表示是因為你不能保證你這個簽名的結果一定是發送方生成的真簽名相反有可能被人篡改過,甚至掉了包。為了描述簡便,下面仍用(r, s, M) 代替(r’, s’, M’)。

    為了驗證(r, s, M) 的簽名是否確由發送方所簽,驗證方需要有(g, p, q, y),驗證過程如下:

  • 計算 w = s^(-1) mod q
  • 計算 u1 = (SHA(M) * w) mod q
  • 計算 u2 = (r * w) mod q
  • 計算 v = (((g^u1) * (y^u2)) mod p ) mod q = ((g^u1 mod p) * (y^u2 mod p) mod p) mod q = (powm(g, u1, p) * powm(y, u2, p) mod p) mod q
  • 若 v等于 r,則通過驗證,否則驗證失敗
  • 注:

  • 驗證通過說明:簽名(r, s) 有效,即(r, s, M) 確為發送方的真實簽名結果,真實性可以高度信任,M未被篡改,為有效信息。
  • 驗證失敗說明:簽名(r, s) 無效,即(r, s, M) 不可靠,或者M被篡改過,或者簽名是偽造的,或者M的簽名有誤,M為無效信息。
  • DSA 算法實現

    DSA密鑰生成:

    public static Map<String, Object> initKey(String seed) throws Exception {KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);// 初始化隨機產生器 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; }

    用私鑰對信息生成數字簽名:

    public static String sign(byte[] data, String privateKey) throws Exception {// 解密由base64編碼的私鑰 byte[] keyBytes = Base64.decodeBase64(privateKey);// 構造PKCS8EncodedKeySpec對象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取私鑰匙對象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);// 用私鑰對信息生成數字簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(priKey);signature.update(data);return Base64.encodeBase64String(signature.sign()); }

    校驗數字簽名:

    public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {// 解密由base64編碼的公鑰 byte[] keyBytes = Base64.decodeBase64(publicKey);// 構造X509EncodedKeySpec對象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取公鑰匙對象 PublicKey pubKey = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(pubKey);signature.update(data);// 驗證簽名是否正常 return signature.verify(Base64.decodeBase64(sign)); }

    查看完整代碼請訪問:

    https://github.com/ForTheDevelopers/JavaSecurity

    總結

    DSA 算法應該屬于數字簽名屆的翹楚了,非對稱密鑰大大增強了算法的安全性,目前已經被廣泛應用到數字簽名領域。

    創作不易,如果大家喜歡本文,歡迎點贊,轉發,你的關注是我們繼續前進的動力_

    com/ForTheDevelopers/JavaSecurity)

    總結

    DSA 算法應該屬于數字簽名屆的翹楚了,非對稱密鑰大大增強了算法的安全性,目前已經被廣泛應用到數字簽名領域。

    創作不易,如果大家喜歡本文,歡迎點贊,轉發,你的關注是我們繼續前進的動力_

    關于作者
    • 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

    聯系作者
    • 微信號:ForTheDeveloper

    • 公眾號:ForTheDevelopers

    總結

    以上是生活随笔為你收集整理的奇妙的安全旅行之DSA算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。