Java加密算法 DSA 和 数字签名

x33g5p2x  于2021-12-25 转载在 其他  
字(4.7k)|赞(0)|评价(0)|浏览(363)
  1. package com.stone.security;
  2. import java.security.Key;
  3. import java.security.KeyFactory;
  4. import java.security.KeyPair;
  5. import java.security.KeyPairGenerator;
  6. import java.security.PrivateKey;
  7. import java.security.PublicKey;
  8. import java.security.SecureRandom;
  9. import java.security.Signature;
  10. import java.security.spec.PKCS8EncodedKeySpec;
  11. import java.security.spec.X509EncodedKeySpec;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import sun.misc.BASE64Decoder;
  15. import sun.misc.BASE64Encoder;
  16. /**
  17. * DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。
  18. * 简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。
  19. * 如果数据和签名不匹配则认为验证失败!即 传输中的数据 可以不再加密,接收方获得数据后,拿到公钥与签名 验证数据是否有效
  20. *
  21. * @author stone
  22. * @date 2014-03-11 09:50:51
  23. */
  24. public class DSA {
  25. //不仅可以使用DSA算法,同样也可以使用RSA算法做数字签名
  26. /*public static final String KEY_ALGORITHM = "RSA";
  27. public static final String SIGNATURE_ALGORITHM = "MD5withRSA";*/
  28. public static final String KEY_ALGORITHM = "DSA";
  29. public static final String SIGNATURE_ALGORITHM = "DSA";
  30. public static final String DEFAULT_SEED = "$%^*%^()(HJG8awfjas7"; //默认种子
  31. public static final String PUBLIC_KEY = "DSAPublicKey";
  32. public static final String PRIVATE_KEY = "DSAPrivateKey";
  33. public static void main(String[] args) throws Exception {
  34. String str = "!@#$!#^$#&ZXVDF呆军工路爱着你*()_+";
  35. byte[] data = str.getBytes();
  36. Map<String, Object> keyMap = initKey();// 构建密钥
  37. PublicKey publicKey = (PublicKey) keyMap.get(PUBLIC_KEY);
  38. PrivateKey privateKey = (PrivateKey) keyMap.get(PRIVATE_KEY);
  39. System.out.println("私钥format:" + privateKey.getFormat());
  40. System.out.println("公钥format:" + publicKey.getFormat());
  41. // 产生签名
  42. String sign = sign(data, getPrivateKey(keyMap));
  43. // 验证签名
  44. boolean verify1 = verify("aaa".getBytes(), getPublicKey(keyMap), sign);
  45. System.err.println("经验证 数据和签名匹配:" + verify1);
  46. boolean verify = verify(data, getPublicKey(keyMap), sign);
  47. System.err.println("经验证 数据和签名匹配:" + verify);
  48. }
  49. /**
  50. * 生成密钥
  51. *
  52. * @param seed 种子
  53. * @return 密钥对象
  54. * @throws Exception
  55. */
  56. public static Map<String, Object> initKey(String seed) throws Exception {
  57. System.out.println("生成密钥");
  58. KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
  59. SecureRandom secureRandom = new SecureRandom();
  60. secureRandom.setSeed(seed.getBytes());
  61. //Modulus size must range from 512 to 1024 and be a multiple of 64
  62. keygen.initialize(640, secureRandom);
  63. KeyPair keys = keygen.genKeyPair();
  64. PrivateKey privateKey = keys.getPrivate();
  65. PublicKey publicKey = keys.getPublic();
  66. Map<String, Object> map = new HashMap<String, Object>(2);
  67. map.put(PUBLIC_KEY, publicKey);
  68. map.put(PRIVATE_KEY, privateKey);
  69. return map;
  70. }
  71. /**
  72. * 生成默认密钥
  73. *
  74. * @return 密钥对象
  75. * @throws Exception
  76. */
  77. public static Map<String, Object> initKey() throws Exception {
  78. return initKey(DEFAULT_SEED);
  79. }
  80. /**
  81. * 取得私钥
  82. *
  83. * @param keyMap
  84. * @return
  85. * @throws Exception
  86. */
  87. public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
  88. Key key = (Key) keyMap.get(PRIVATE_KEY);
  89. return encryptBASE64(key.getEncoded()); //base64加密私钥
  90. }
  91. /**
  92. * 取得公钥
  93. *
  94. * @param keyMap
  95. * @return
  96. * @throws Exception
  97. */
  98. public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
  99. Key key = (Key) keyMap.get(PUBLIC_KEY);
  100. return encryptBASE64(key.getEncoded()); //base64加密公钥
  101. }
  102. /**
  103. * 用私钥对信息进行数字签名
  104. * @param data 加密数据
  105. * @param privateKey 私钥-base64加密的
  106. * @return
  107. * @throws Exception
  108. */
  109. public static String sign(byte[] data, String privateKey) throws Exception {
  110. System.out.println("用私钥对信息进行数字签名");
  111. byte[] keyBytes = decryptBASE64(privateKey);
  112. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  113. KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
  114. PrivateKey priKey = factory.generatePrivate(keySpec);//生成 私钥
  115. //用私钥对信息进行数字签名
  116. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  117. signature.initSign(priKey);
  118. signature.update(data);
  119. return encryptBASE64(signature.sign());
  120. }
  121. /**
  122. * BASE64Encoder 加密
  123. * @param data 要加密的数据
  124. * @return 加密后的字符串
  125. */
  126. private static String encryptBASE64(byte[] data) {
  127. BASE64Encoder encoder = new BASE64Encoder();
  128. String encode = encoder.encode(data);
  129. return encode;
  130. }
  131. /**
  132. * BASE64Decoder 解密
  133. * @param data 要解密的字符串
  134. * @return 解密后的byte[]
  135. * @throws Exception
  136. */
  137. private static byte[] decryptBASE64(String data) throws Exception {
  138. BASE64Decoder decoder = new BASE64Decoder();
  139. byte[] buffer = decoder.decodeBuffer(data);
  140. return buffer;
  141. }
  142. /**
  143. * 校验数字签名
  144. * @param data 加密数据
  145. * @param publicKey
  146. * @param sign 数字签名
  147. * @return
  148. * @throws Exception
  149. */
  150. public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
  151. byte[] keyBytes = decryptBASE64(publicKey);
  152. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  153. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  154. PublicKey pubKey = keyFactory.generatePublic(keySpec);
  155. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  156. signature.initVerify(pubKey);
  157. signature.update(data);
  158. return signature.verify(decryptBASE64(sign)); //验证签名
  159. }
  160. }

参考地址:http://63938525.iteye.com/blog/1051565

http://www.iteye.com/topic/1122076 

相关文章