当前位置:   article > 正文

Java实现基于RSA的数字签名

Java实现基于RSA的数字签名

加密与数字签名的区别

1、加密保证了数据接受方的数据安全性。加密的作用是防止泄密。

2、签名保证了数据发送方的数据安全性。签名的作用是防止篡改。

数字签名的应用

问题:在比特币中,怎么证明这个交易是你发布的?

这是就需要用到数字签名,数字签名大概可已描述为:用私钥加密,用公钥解密。发布一条交易信息:“我给xxx转了0.2个比特币”,将这条消息用自己的私钥加密,再发布出去,大众在收到这条消息后,用我的公钥验签,验证成功则说明是我发布的交易。

签名的过程与加密相反。

代码

  1. package RSA;
  2. import org.apache.commons.codec.binary.Base64;
  3. import java.io.BufferedReader;
  4. import java.io.FileReader;
  5. import java.security.*;
  6. import java.security.interfaces.RSAPrivateKey;
  7. import java.security.interfaces.RSAPublicKey;
  8. import java.security.spec.PKCS8EncodedKeySpec;
  9. import java.security.spec.X509EncodedKeySpec;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. /**
  13. * @author WuYongheng
  14. * @date 2022/11/22
  15. * @description 数字签名 RSA
  16. */
  17. public class RsaSignature {
  18. //数字签名 - 签名验证算法
  19. private static final String SIGNATRUE_ALGORITHM = "MD5withRSA";
  20. //数字签名 - RSA算法
  21. private static final String KEY_ALGORITHM = "RSA";
  22. //私钥
  23. private static final String PRIVATEKEY = "RSAPrivateKey";
  24. //公钥
  25. private static final String PUBLICKEY = "RSAPublicKey";
  26. /**
  27. * RSA长度
  28. * 默认是 1024
  29. * 必须是 64的倍数
  30. * 范围:512 - 65536
  31. */
  32. private static final int KeySize = 512; // 512 位 2进制,128 位 16进制
  33. /**
  34. * 初始化
  35. *
  36. * @return map
  37. * @throws Exception
  38. */
  39. public static Map<String, Object> initKey() throws Exception {
  40. //实例化,生成器
  41. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
  42. //初始化
  43. keyPairGenerator.initialize(KeySize);
  44. //获取公私钥对
  45. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  46. //获取私钥
  47. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  48. //获取公钥
  49. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  50. Map<String, Object> map = new HashMap<String, Object>();
  51. map.put(PRIVATEKEY, privateKey);
  52. map.put(PUBLICKEY, publicKey);
  53. return map;
  54. }
  55. /**
  56. * 取得公钥
  57. *
  58. * @param map
  59. * @return byte[]
  60. */
  61. public static byte[] getPublicKey(Map<String, Object> map) {
  62. PublicKey publicKey = (PublicKey) map.get(PUBLICKEY);
  63. return publicKey.getEncoded();
  64. }
  65. /**
  66. * 取得私钥
  67. *
  68. * @param map
  69. * @return byte[]
  70. */
  71. public static byte[] getPrivateKey(Map<String, Object> map) {
  72. PrivateKey privateKey = (PrivateKey) map.get(PRIVATEKEY);
  73. return privateKey.getEncoded();
  74. }
  75. /**
  76. * 私钥加密
  77. *
  78. * @param source 数据
  79. * @param key 私钥
  80. * @return 签名
  81. * @throws Exception
  82. */
  83. public static String sign(String source, byte[] key) throws Exception {
  84. byte[] data = source.getBytes("utf-8");
  85. // 取得私钥
  86. PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
  87. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  88. // 生成私钥
  89. PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  90. //新增: 实例化 签名对象
  91. Signature signature = Signature.getInstance(SIGNATRUE_ALGORITHM);
  92. //初始化 私钥
  93. signature.initSign(privateKey);
  94. //更新签名
  95. signature.update(data);
  96. byte[] enSign = signature.sign();
  97. return Base64.encodeBase64String(enSign);
  98. }
  99. /**
  100. * 校验
  101. *
  102. * @param source 源数据
  103. * @param key 公钥
  104. * @param signStr 已签名的数据
  105. * @return true or false
  106. * @throws Exception
  107. */
  108. public static boolean verify(String source, byte[] key, String signStr) throws Exception {
  109. // 还原即将 解密的 数据源
  110. byte[] data = source.getBytes("utf-8");
  111. // 还原已签名数据
  112. byte[] signData = Base64.decodeBase64(signStr);
  113. // 取得公钥
  114. X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
  115. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  116. // 生成公钥
  117. PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
  118. //新增: 实例化 签名对象
  119. Signature signature = Signature.getInstance(SIGNATRUE_ALGORITHM);
  120. //初始化 校验公钥
  121. signature.initVerify(publicKey);
  122. //更新签名
  123. signature.update(data);
  124. //验证
  125. return signature.verify(signData);
  126. }
  127. public static void main(String[] args) throws Exception {
  128. Map<String, Object> keyMap = initKey();
  129. byte[] privateKey = getPrivateKey(keyMap);
  130. byte[] publicKey = getPublicKey(keyMap);
  131. System.out.println("获取的私钥:" + Base64.encodeBase64String(privateKey));
  132. System.out.println("获取的公钥:" + Base64.encodeBase64String(publicKey));
  133. String source = "";
  134. //需要签名文件的内容
  135. String fileName = "D:\\code\\aaa.txt";
  136. try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
  137. String line;
  138. while ((line = br.readLine()) != null) {
  139. System.out.println("文件内容是: " + line);
  140. source = line;
  141. }
  142. }
  143. System.out.println("需要签名的文件内容是: " + source);
  144. String sign = sign(source, privateKey);
  145. System.out.println("签名后:" + sign);
  146. boolean flat = verify(source, publicKey, sign);
  147. System.out.println("校验结果:" + flat);
  148. }
  149. }

效果

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号