前言
参考文档:https://blog.csdn.net/sinat_40770656/article/details/131225221?spm=1001.2014.3001.5501
系统有需求,不能明文传输密码,而系统本身还没有采用https,那么只能自己实现一层加密,像前后端数据传输最安全的办法就是使用非对称加密,这里采用RSA
前端加密
前端通过RSA加密可以通过jsrsasign库,官方地址:https://github.com/kjur/jsrsasign
这里只采用传统的html方式使用jsrsasign库,使用公钥进行加密
1 2 3 4 5 6 7 8 9 10
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js"></script> <script> let publicKey = "-----BEGIN PUBLIC KEY-----\n" + "****************************************" + "-----END PUBLIC KEY-----"; function encrypt(password){ let keyObj = KEYUTIL.getKey(publicKey); return KJUR.crypto.Cipher.encrypt(password, keyObj, 'RSA'); } </script>
|
代码中的KEYUTIL和KJUR都是jsrsasign-all-min.js中定义好的对象,可以直接使用。
需要注意KJUR.crypto.Cipher.encrypt方法加密出来的结果是16进制字符串,在后端解密的时候要记得处理一下
后端解密
Java似乎默认支持RSA算法,这里引入了bouncycastle以简化代码
1 2 3 4 5
| <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> </dependency>
|
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
| private String privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" + "*****************************************************" + "-----END RSA PRIVATE KEY-----";
public String decrypt(String password){ try{ byte[] bytes = hexStringToByteArray(password); PEMParser pemParser = new PEMParser(new StringReader(privateKey)); PEMKeyPair pemKeyPair = ((PEMKeyPair) pemParser.readObject()); PrivateKeyInfo privateKeyInfo = pemKeyPair.getPrivateKeyInfo(); PrivateKey privateKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] data = cipher.doFinal(bytes); return new String(data); }catch (Exception e){ } }
public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; }
|
hexStringToByteArray放是为了将jsrsasign加密出来的16进制字符串转为byte数组