Java加密技术(六)——数字签名算法DSA

本文深入探讨了DSA数字签名的原理与应用,并通过Java代码示例展示了如何生成与验证数字签名,确保数据在传输过程中的完整性和真实性。


接下来我们介绍DSA数字签名,非对称加密的另一种实现。
DSA
DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!


通过java代码实现如下: Coder类见Java加密技术(一)
Java代码 收藏代码
  1. importjava.security.Key;
  2. importjava.security.KeyFactory;
  3. importjava.security.KeyPair;
  4. importjava.security.KeyPairGenerator;
  5. importjava.security.PrivateKey;
  6. importjava.security.PublicKey;
  7. importjava.security.SecureRandom;
  8. importjava.security.Signature;
  9. importjava.security.interfaces.DSAPrivateKey;
  10. importjava.security.interfaces.DSAPublicKey;
  11. importjava.security.spec.PKCS8EncodedKeySpec;
  12. importjava.security.spec.X509EncodedKeySpec;
  13. importjava.util.HashMap;
  14. importjava.util.Map;
  15. /**
  16. *DSA安全编码组件
  17. *
  18. *@author梁栋
  19. *@version1.0
  20. *@since1.0
  21. */
  22. publicabstractclassDSACoderextendsCoder{
  23. publicstaticfinalStringALGORITHM="DSA";
  24. /**
  25. *默认密钥字节数
  26. *
  27. *<pre>
  28. *DSA
  29. *DefaultKeysize1024
  30. *Keysizemustbeamultipleof64,rangingfrom512to1024(inclusive).
  31. *</pre>
  32. */
  33. privatestaticfinalintKEY_SIZE=1024;
  34. /**
  35. *默认种子
  36. */
  37. privatestaticfinalStringDEFAULT_SEED="0f22507a10bbddd07d8a3082122966e3";
  38. privatestaticfinalStringPUBLIC_KEY="DSAPublicKey";
  39. privatestaticfinalStringPRIVATE_KEY="DSAPrivateKey";
  40. /**
  41. *用私钥对信息生成数字签名
  42. *
  43. *@paramdata
  44. *加密数据
  45. *@paramprivateKey
  46. *私钥
  47. *
  48. *@return
  49. *@throwsException
  50. */
  51. publicstaticStringsign(byte[]data,StringprivateKey)throwsException{
  52. //解密由base64编码的私钥
  53. byte[]keyBytes=decryptBASE64(privateKey);
  54. //构造PKCS8EncodedKeySpec对象
  55. PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);
  56. //KEY_ALGORITHM指定的加密算法
  57. KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM);
  58. //取私钥匙对象
  59. PrivateKeypriKey=keyFactory.generatePrivate(pkcs8KeySpec);
  60. //用私钥对信息生成数字签名
  61. Signaturesignature=Signature.getInstance(keyFactory.getAlgorithm());
  62. signature.initSign(priKey);
  63. signature.update(data);
  64. returnencryptBASE64(signature.sign());
  65. }
  66. /**
  67. *校验数字签名
  68. *
  69. *@paramdata
  70. *加密数据
  71. *@parampublicKey
  72. *公钥
  73. *@paramsign
  74. *数字签名
  75. *
  76. *@return校验成功返回true失败返回false
  77. *@throwsException
  78. *
  79. */
  80. publicstaticbooleanverify(byte[]data,StringpublicKey,Stringsign)
  81. throwsException{
  82. //解密由base64编码的公钥
  83. byte[]keyBytes=decryptBASE64(publicKey);
  84. //构造X509EncodedKeySpec对象
  85. X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes);
  86. //ALGORITHM指定的加密算法
  87. KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM);
  88. //取公钥匙对象
  89. PublicKeypubKey=keyFactory.generatePublic(keySpec);
  90. Signaturesignature=Signature.getInstance(keyFactory.getAlgorithm());
  91. signature.initVerify(pubKey);
  92. signature.update(data);
  93. //验证签名是否正常
  94. returnsignature.verify(decryptBASE64(sign));
  95. }
  96. /**
  97. *生成密钥
  98. *
  99. *@paramseed
  100. *种子
  101. *@return密钥对象
  102. *@throwsException
  103. */
  104. publicstaticMap<String,Object>initKey(Stringseed)throwsException{
  105. KeyPairGeneratorkeygen=KeyPairGenerator.getInstance(ALGORITHM);
  106. //初始化随机产生器
  107. SecureRandomsecureRandom=newSecureRandom();
  108. secureRandom.setSeed(seed.getBytes());
  109. keygen.initialize(KEY_SIZE,secureRandom);
  110. KeyPairkeys=keygen.genKeyPair();
  111. DSAPublicKeypublicKey=(DSAPublicKey)keys.getPublic();
  112. DSAPrivateKeyprivateKey=(DSAPrivateKey)keys.getPrivate();
  113. Map<String,Object>map=newHashMap<String,Object>(2);
  114. map.put(PUBLIC_KEY,publicKey);
  115. map.put(PRIVATE_KEY,privateKey);
  116. returnmap;
  117. }
  118. /**
  119. *默认生成密钥
  120. *
  121. *@return密钥对象
  122. *@throwsException
  123. */
  124. publicstaticMap<String,Object>initKey()throwsException{
  125. returninitKey(DEFAULT_SEED);
  126. }
  127. /**
  128. *取得私钥
  129. *
  130. *@paramkeyMap
  131. *@return
  132. *@throwsException
  133. */
  134. publicstaticStringgetPrivateKey(Map<String,Object>keyMap)
  135. throwsException{
  136. Keykey=(Key)keyMap.get(PRIVATE_KEY);
  137. returnencryptBASE64(key.getEncoded());
  138. }
  139. /**
  140. *取得公钥
  141. *
  142. *@paramkeyMap
  143. *@return
  144. *@throwsException
  145. */
  146. publicstaticStringgetPublicKey(Map<String,Object>keyMap)
  147. throwsException{
  148. Keykey=(Key)keyMap.get(PUBLIC_KEY);
  149. returnencryptBASE64(key.getEncoded());
  150. }
  151. }


再给出一个测试类:
Java代码 收藏代码
  1. importstaticorg.junit.Assert.*;
  2. importjava.util.Map;
  3. importorg.junit.Test;
  4. /**
  5. *
  6. *@author梁栋
  7. *@version1.0
  8. *@since1.0
  9. */
  10. publicclassDSACoderTest{
  11. @Test
  12. publicvoidtest()throwsException{
  13. StringinputStr="abc";
  14. byte[]data=inputStr.getBytes();
  15. //构建密钥
  16. Map<String,Object>keyMap=DSACoder.initKey();
  17. //获得密钥
  18. StringpublicKey=DSACoder.getPublicKey(keyMap);
  19. StringprivateKey=DSACoder.getPrivateKey(keyMap);
  20. System.err.println("公钥:\r"+publicKey);
  21. System.err.println("私钥:\r"+privateKey);
  22. //产生签名
  23. Stringsign=DSACoder.sign(data,privateKey);
  24. System.err.println("签名:\r"+sign);
  25. //验证签名
  26. booleanstatus=DSACoder.verify(data,publicKey,sign);
  27. System.err.println("状态:\r"+status);
  28. assertTrue(status);
  29. }
  30. }

控制台输出:
Console代码 收藏代码
  1. 公钥:
  2. MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp
  3. RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn
  4. xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE
  5. C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ
  6. FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
  7. g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv
  8. 5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9
  9. 21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=
  10. 私钥:
  11. MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2
  12. USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4
  13. O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC
  14. ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB
  15. gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR
  16. kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q
  17. 签名:
  18. MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=
  19. 状态:
  20. true


注意状态为true,就验证成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值