服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - JAVA 中解密RSA算法JS加密实例详解

JAVA 中解密RSA算法JS加密实例详解

2020-09-10 15:38Java教程网 Java教程

这篇文章主要介绍了JAVA 中解密RSA算法JS加密 的相关资料,需要的朋友可以参考下

JAVA 中解密RSA算法JS加密实例详解

有这样一个需求,前端登录的用户名密码,密码必需加密,但不可使用MD5,因为后台要检测密码的复杂度,那么在保证安全的前提下将密码传到后台呢,答案就是使用RSA非对称加密算法解决 。

java代码

需要依赖 commons-codec 包

RSACoder.Java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import org.apache.commons.codec.binary.Base64;
 
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
 
/**
 * Created by lake on 17-4-12.
 */
public class RSACoder {
  public static final String KEY_ALGORITHM = "RSA";
  public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
 
  private static final String PUBLIC_KEY = "RSAPublicKey";
  private static final String PRIVATE_KEY = "RSAPrivateKey";
 
  public static byte[] decryptBASE64(String key) {
    return Base64.decodeBase64(key);
  }
 
  public static String encryptBASE64(byte[] bytes) {
    return Base64.encodeBase64String(bytes);
  }
 
  /**
   * 用私钥对信息生成数字签名
   *
   * @param data    加密数据
   * @param privateKey 私钥
   * @return
   * @throws Exception
   */
  public static String sign(byte[] data, String privateKey) throws Exception {
    // 解密由base64编码的私钥
    byte[] keyBytes = decryptBASE64(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 encryptBASE64(signature.sign());
  }
 
  /**
   * 校验数字签名
   *
   * @param data   加密数据
   * @param publicKey 公钥
   * @param sign   数字签名
   * @return 校验成功返回true 失败返回false
   * @throws Exception
   */
  public static boolean verify(byte[] data, String publicKey, String sign)
      throws Exception {
    // 解密由base64编码的公钥
    byte[] keyBytes = decryptBASE64(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(decryptBASE64(sign));
  }
 
  public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得私钥
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }
 
  /**
   * 解密<br>
   * 用私钥解密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] decryptByPrivateKey(String data, String key)
      throws Exception {
    return decryptByPrivateKey(decryptBASE64(data),key);
  }
 
  /**
   * 解密<br>
   * 用公钥解密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] decryptByPublicKey(byte[] data, String key)
      throws Exception {
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得公钥
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key publicKey = keyFactory.generatePublic(x509KeySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, publicKey);
    return cipher.doFinal(data);
  }
 
  /**
   * 加密<br>
   * 用公钥加密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] encryptByPublicKey(String data, String key)
      throws Exception {
    // 对公钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得公钥
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key publicKey = keyFactory.generatePublic(x509KeySpec);
    // 对数据加密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    return cipher.doFinal(data.getBytes());
  }
 
  /**
   * 加密<br>
   * 用私钥加密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] encryptByPrivateKey(byte[] data, String key)
      throws Exception {
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得私钥
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据加密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }
 
  /**
   * 取得私钥
   *
   * @param keyMap
   * @return
   * @throws Exception
   */
  public static String getPrivateKey(Map<String, Key> keyMap)
      throws Exception {
    Key key = (Key) keyMap.get(PRIVATE_KEY);
    return encryptBASE64(key.getEncoded());
  }
 
  /**
   * 取得公钥
   *
   * @param keyMap
   * @return
   * @throws Exception
   */
  public static String getPublicKey(Map<String, Key> keyMap)
      throws Exception {
    Key key = keyMap.get(PUBLIC_KEY);
    return encryptBASE64(key.getEncoded());
  }
 
  /**
   * 初始化密钥
   *
   * @return
   * @throws Exception
   */
  public static Map<String, Key> initKey() throws Exception {
    KeyPairGenerator keyPairGen = KeyPairGenerator
        .getInstance(KEY_ALGORITHM);
    keyPairGen.initialize(1024);
    KeyPair keyPair = keyPairGen.generateKeyPair();
    Map<String, Key> keyMap = new HashMap(2);
    keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥
    keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥
    return keyMap;
  }
}

测试类

RSACoderTest.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import org.junit.Before;
import org.junit.Test;
 
import java.security.Key;
import java.util.Map;
 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
 
/**
 * Created by lake on 17-4-12.
 */
public class RSACoderTest {
  private String publicKey;
  private String privateKey;
 
  @Before
  public void setUp() throws Exception {
    Map<String, Key> keyMap = RSACoder.initKey();
    publicKey = RSACoder.getPublicKey(keyMap);
    privateKey = RSACoder.getPrivateKey(keyMap);
    System.err.println("公钥: \n\r" + publicKey);
    System.err.println("私钥: \n\r" + privateKey);
  }
 
  @Test
  public void test() throws Exception {
    System.err.println("公钥加密——私钥解密");
    String inputStr = "abc";
    byte[] encodedData = RSACoder.encryptByPublicKey(inputStr, publicKey);
    byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
        privateKey);
    String outputStr = new String(decodedData);
    System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
    assertEquals(inputStr, outputStr);
  }
 
  @Test
  public void testSign() throws Exception {
    System.err.println("私钥加密——公钥解密");
    String inputStr = "sign";
    byte[] data = inputStr.getBytes();
    byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
    byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);
    String outputStr = new String(decodedData);
    System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
    assertEquals(inputStr, outputStr);
    System.err.println("私钥签名——公钥验证签名");
    // 产生签名
    String sign = RSACoder.sign(encodedData, privateKey);
    System.err.println("签名:" + sign);
    // 验证签名
    boolean status = RSACoder.verify(encodedData, publicKey, sign);
    System.err.println("状态:" + status);
    assertTrue(status);
  }
}

前端代码

依赖 jsencrypt 项目

?
1
2
3
4
5
6
<script src="bin/jsencrypt.min.js"></script>
<script type="text/javascript">
  var encrypt = new JSEncrypt();
  encrypt.setPublicKey('java生成的公钥');
  var encrypted = encrypt.encrypt('加密的字符串');
</script>

说明

前端生成加密的字符串encrypted,传到后台,java使用私钥进行解密即可。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

延伸 · 阅读

精彩推荐