如何编写示例代码实现Java后端对接前端jsencrypt.js加密数据的解密过程?

2026-05-24 01:121阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3854个文字,预计阅读时间需要16分钟。

如何编写示例代码实现Java后端对接前端jsencrypt.js加密数据的解密过程?

目录

1.什么是RSA

2.RSA算法

2.1 生成公钥和私钥 2.2 使用公钥加密信息 2.3 使用私钥解密信息

3.RSA的应用

3.1 数字签名

4.RSA的安全性

5.为什么写这篇文章

6.前端代码

7.后端代码

1.什么是RSA

计算机加密算法RSA是一种广泛使用的公钥加密技术。

目录
  • 1.什么是RSA
  • 2.RSA算法
    • 2.1 生成公钥和私钥
    • 2.2 使用公钥加密信息
    • 2.3 使用私钥解密信息
  • 4.RSA的应用:数字签名
    • 5.RSA的安全性
      • 6.为什么要写这文章
        • 7.前端代码
          • 8.后端代码

            1.什么是RSA

            计算机中常用的加密技术分为两类:对称加密、非对称加密。

            RSA属于非对称加密。加密、解密过程使用不同的秘钥,分为公钥、私钥。公钥可以公开,私钥不可以。

            对称加密:加密和解密使用相同的的秘钥Key,这个Key需要在网络上传输,不安全,因此需要非对称加密。

            2.RSA算法

            2.1 生成公钥和私钥

            (1)随意选择两个大的素数P和Q,P不等于Q;

            (2)令 N = P × Q 、 T = ( P − 1 ) × ( Q − 1 ) N = P \times Q、T = (P - 1) \times (Q - 1) N=P×Q、T=(P−1)×(Q−1);

            (3)选择一个整数E作为秘钥,需要满足:gcd(E, T)=1 && E<T;

            (4)根据 ( D × E ) m o d T = 1 (D \times E) \ mod \ T = 1 (D×E) mod T=1,计算出D,作为另一个秘钥;

            (5)使用PK=(N、E)作为公钥、SK=(N, D)作为私钥(当然可以反过来)。

            2.2 使用公钥加密信息

            使用PK=(N、E)公钥加密信息。

            若明文为M,则密文C可以按照如下计算得到(要求M<N)

            2.3 使用私钥解密信息

            使用SK=(N, D)私钥解密信息。

            如密文为C,则明文M可以按照如下计算得到:

            4.RSA的应用:数字签名

            数字签名是实现安全交易的核心技术之一,实现基础是RSA加密技术。

            数字签名类似于我们生活中的手写签名,必须保证签名的人事后不能抵赖,同时不能让别人伪造我们的签名。因此数字签名需要保证:

            (1)发送者事后不能抵赖对报文的签名;

            (2)接受者不能伪造对报文的签名。

            如果A向B发送报文M,A手中有私钥,公钥是公开的,A给M使用私钥进行加密再发给B即可。

            这样即可保证上述两点:

            (1)因为只有A可以对M使用私钥进行加密,A不能抵赖;

            (2)B用公钥可以得到原始信息M,如果伪造成M’,则A可以证明其伪造了信息。

            在解密之前我们先进行验签操作,如果验签失败,则认为内容是伪造,不进行解密。

            5.RSA的安全性

            RSA算法的安全性依赖于大数分解。因此为了保证安全性,需要使得P、Q非常大。

            因为数据很大,又牵涉到幂次运算,因此计算量很大。

            6.为什么要写这文章

            因为我想做一个数据加密,就开始了解Rsa加密算法,实现一个前端加密,后端解密的一个过程,然后我也不想重复造轮子,就上百度搜索,发现好多文章都是抄来抄去去的根本不合适。所以只好自己写了一个记录,以便到时候要用的时候再看,前端使用jsencrypt.js进行加密,然后在使用的时候我发现这个内容过长无法加密,然后又找了个扩展的,可以使用长内容加密,但是到后台解密的时候出问题了,无法解密出正确内容,我只好换回原理的版本,然后自己重写了两个方法来进行扩展,实现长内容加密。这个改进后的方法按理论可以进行很大文本文本加密传输,但是具体能承载多长我没有测试过,尽量不要使用rsa加密来加密比较长的文本,因为rsa加密是比较麻烦的,复杂度比较高,在加密之前也要考虑那些数据需要加密,那些数据不需要加密,不要通通都加密,这样解密的时候会浪费许多时间,增加服务器的压力,访问时间过长。

            因为Rsa加密算法还是稍微复杂,我就不过的阐述,直接看源码吧,先复制过去能跑,然后再自己上网搜索,相关内容进行脑补,这个改进估计会存在问题,因为加密的长度限制117,和每次加密后的内容长度172 ,我不太清楚是不是固定的,我尝试了很多次都没有出现问题,等出现问题再解决吧。

            7.前端代码

            <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <script src="../js/jsencrypt.js" type="text/javascript" charset="utf-8"></script> <script src="../js/jquery1.42.min.js" type="text/javascript" charset="utf-8"></script> <body> <script type="text/javascript"> /** * 对加密工具进行封装 */ let RsaUtil = { publicKey: '', privateKey: '', rsaEncrypt: {}, // 长文本加密 encryptLong: function(content) { let encryptionSectionSize = 117; content = encodeURIComponent(content); let ciphertext = ''; if (content && content.length > encryptionSectionSize) { let paragraphic = content.length / encryptionSectionSize; let isIntger = (paragraphic | 0) === paragraphic; let encryptionCountet = parseInt(paragraphic); if (isIntger) { for (let i = 0; i < encryptionCountet; i++) { ciphertext += this.rsaEncrypt.encrypt(content.substring(i * encryptionSectionSize, (i * encryptionSectionSize) + encryptionSectionSize)); } } else { let lastContentLength = content.length % encryptionSectionSize; for (let i = 0; i < encryptionCountet; i++) { ciphertext += this.rsaEncrypt.encrypt(content.substring(i * encryptionSectionSize, (i * encryptionSectionSize) + encryptionSectionSize)); } ciphertext += this.rsaEncrypt.encrypt(content.substring(encryptionCountet * encryptionSectionSize, encryptionCountet * encryptionSectionSize + lastContentLength)); } } else { ciphertext = this.rsaEncrypt.encrypt(content); } return ciphertext; }, // 长文本解密 decryptLong: function(content) { let decodeSectionSize = 172; let decodeText = ''; let isFinish = false; if (content && content.length > decodeSectionSize) { let paragraphic = content.length / decodeSectionSize; let isIntger = (paragraphic | 0) === paragraphic; let encryptionCountet = parseInt(paragraphic); if (isIntger) { for (let i = 0; i < encryptionCountet; i++) { decodeText += this.rsaEncrypt.decrypt(content.substring(i * decodeSectionSize, (i * decodeSectionSize) + decodeSectionSize)); isFinish = decodeText.indexOf('false') !== -1; if (isFinish) { return isFinish; } } } else { let lastContentLength = content.length % decodeSectionSize; for (let i = 0; i < encryptionCountet; i++) { decodeText += this.rsaEncrypt.encrypt(content.substring(i * decodeSectionSize, (i * decodeSectionSize) + decodeSectionSize)); isFinish = decodeText.indexOf('false') !== -1; if (isFinish) { return isFinish; } } decodeText += this.rsaEncrypt.encrypt(content.substring(encryptionCountet * decodeSectionSize, encryptionCountet * decodeSectionSize + lastContentLength)); } } else { decodeText = this.rsaEncrypt.decrypt(content); } return decodeURIComponent(decodeText); }, // 小于117长度的字符串加密 encrypt: function(content) { return this.encrypt(content); }, // 小于117长度的字符串解密 decrypt: function(content) { return this.decrypt(content); }, // 初始化RsaUtil工具对象 init: function(publicKey, privateKey) { if (!publicKey) { throw new Error('publicKey cant't null'); } let rsaEncrypt = new JSEncrypt(); rsaEncrypt.setPublicKey(publicKey); if (privateKey) { rsaEncrypt.setPrivateKey(privateKey); } this.publicKey = publicKey; this.privateKey = privateKey; this.rsaEncrypt = rsaEncrypt; } } async function getPublicKey() { return new Promise((resolve, reject) => { $.ajax({ url: "localhost:8080/rsa/getPublicKey", type: "GET", data: {}, success: function(data, textStatus) { if (data && data.code === 200 && data.content.length > 0) { resolve(data.content); } else { reject(false); } }, error: function(error) { reject(false); } }); }) } async function privateKeyDecode(content) { return new Promise((resolve, reject) => { $.ajax({ url: "localhost:8080/rsa/privateKeyDecode", type: "POST", contentType: "application/json", dataType: "json", data: JSON.stringify({ content }), success: function(data, textStatus) { if (data && data.code === 200 && data.content.length > 0) { resolve(data.content); } else { resolve(false); } }, error: function(error) { resolve(false); } }); }) } let userInfo = { id: '1564868915154190336', nickName: '小明', sex: '男', email: '1482334546@qq.com', userType: '1', userName: 'admin', password: 'admin666?', createTime: '2022-08-31 14:55', valid: '1', isDelete: '0', headImg: 'profile.csdnimg.cn/7/3/0/2_m0_46188681', } let userInfoStr = JSON.stringify(userInfo) async function dataEncryption() { let publicKey = await getPublicKey(); RsaUtil.init(publicKey); console.log("后台获取到的公钥:" + publicKey) let ciphertext = RsaUtil.encryptLong(userInfoStr); console.log("使用后台公钥加密后的文本:" + ciphertext); let decodeResult = await privateKeyDecode(ciphertext); console.log("使用后台私钥解密后的文本:" + decodeResult) console.log("是否解密成功",decodeResult === userInfoStr) } dataEncryption(); </script> </body> </html>

            8.后端代码

            RsaUtilClient配合 jsencrypt.js 解密的工具类

            import org.springframework.util.Base64Utils; import javax.crypto.Cipher; import java.net.URLDecoder; import java.security.*; import java.security.spec.*; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class RsaUtilClient { 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"; private static volatile ConcurrentHashMap<String,Key> KEY_MAP = new ConcurrentHashMap<>(2); /** * base64解码 * * @param content * @return byte[] * @author compass * @date 2022/9/1 17:12 * @since 1.0.0 **/ public static byte[] decryptBASE64(String content) { return org.springframework.util.Base64Utils.decode(content.getBytes()); } /** * base64编码 * * @param bytes 字符byte数组 * @return java.lang.String * @author compass * @date 2022/9/1 17:12 * @since 1.0.0 **/ public static String encryptBASE64(byte[] bytes) { return new String(org.springframework.util.Base64Utils.encode(bytes)); } /** * 用私钥对信息生成数字签名 * * @param data 加密数据 * @param privateKey 私钥 * @return java.lang.String * @author compass * @date 2022/9/1 14:21 * @since 1.0.0 **/ 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)); } /** * 通过私钥解密 * * @param data 加密的byte数组 * @param privateKey 私钥 * @return byte[] * @author compass * @date 2022/9/1 17:14 * @since 1.0.0 **/ public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(privateKey); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privatizationKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privatizationKey); return cipher.doFinal(data); } /** * 私钥解密前端jsencrypt分段加密的长文本内容, * 前端加密的字符串需要使用encodeURIComponent编码,后端使用URLDecoder.decode解码来解决中文字符串无法解密的问题 * * @param content 加密的内容 * @param privateKey 私钥 * @return java.lang.String * @author compass * @date 2022/9/1 16:53 * @since 1.0.0 **/ public static String jsencryptDecryptByPrivateKeyLong(String content, String privateKey) { String resultContent = ""; try { StringBuffer buffer = new StringBuffer(); if (content != null && content.trim().length() > 0) { String[] contentList = content.split("="); for (String item : contentList) { byte[] itemBytes = Base64Utils.decode((item + "=").getBytes()); try { byte[] itemResultBytes = decryptByPrivateKey(itemBytes, privateKey); String itemResultStr = new String(itemResultBytes); buffer.append(itemResultStr); } catch (Exception e) { e.printStackTrace(); } } } resultContent = URLDecoder.decode(buffer.toString()); } catch (Exception e) { e.printStackTrace(); System.err.println("jsencryptDecryptByPrivateKeyLong解密出错:" + e.getMessage() + ":" + "解密内容:" + content); throw new RuntimeException("rsa解密失败"); } return resultContent; } /** * 通过私钥解密 * * @param data 加密的byte数组 * @param privateKey 私钥 * @return byte[] * @author compass * @date 2022/9/1 17:14 * @since 1.0.0 **/ public static byte[] decryptByPrivateKey(String data, String privateKey) throws Exception { return decryptByPrivateKey(decryptBASE64(data), privateKey); } /** * 解密<br> * * * @param data * @param key * @return * @throws Exception */ /** * 用公钥解密 * * @param data 代解密的byte数组 * @param publicKey * @return byte[] * @author compass * @date 2022/9/1 17:17 * @since 1.0.0 **/ public static byte[] decryptByPublicKey(byte[] data, String publicKey) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(publicKey); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicityKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicityKey); 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 存放私钥和公钥的map集合 * @return java.lang.String * @author compass * @date 2022/9/1 17:18 * @since 1.0.0 **/ public static String getPrivateKey(Map<String, Key> keyMap) { Key key = keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap 放私钥和公钥的map集合 * @return java.lang.String * @author compass * @date 2022/9/1 17:28 * @since 1.0.0 **/ public static String getPublicKey(Map<String, Key> keyMap) { Key key = keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化公钥和秘钥 每次调用可以获取不同的公钥和私钥 * @return java.util.Map<java.lang.String, java.security.Key> * @author compass * @date 2022/9/1 17:28 * @since 1.0.0 **/ public static ConcurrentHashMap<String, Key> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); ConcurrentHashMap<String, Key> keyMap = new ConcurrentHashMap<>(2); keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥 keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥 return keyMap; } /** * 初始化公钥和秘钥 初始化唯一的公钥和私钥 * @return java.util.Map<java.lang.String, java.security.Key> * @author compass * @date 2022/9/1 17:28 * @since 1.0.0 **/ public static Map<String,Key> initKeyOnce() { if (KEY_MAP.size() == 0){ synchronized (RsaUtilClient.class){ if (KEY_MAP.size() == 0){ try { KEY_MAP = initKey(); }catch (Exception e){ e.printStackTrace(); throw new RuntimeException("公钥和私钥初始化失败"); } } } } return KEY_MAP; } public static void main(String[] args) throws Exception { String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWh3Nyt+5QqUXw1qHXM4k7lq98f9wA4iQgKK1LB1tr4uIgL/dls0LkBgY4oS/Dn3J0qHkpUTkTT84uMHey7cwdd9k90/65cpdawX0J0KO3S3Zwl9d5AJt7/hdSap3AcHw3dvlrZvvDJ72AaR3YUPujNM3dhLC7tsdDb3CxoJSBDQIDAQAB"; String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJaHc3K37lCpRfDWodcziTuWr3x/3ADiJCAorUsHW2vi4iAv92WzQuQGBjihL8OfcnSoeSlRORNPzi4wd7LtzB132T3T/rlyl1rBfQnQo7dLdnCX13kAm3v+F1JqncBwfDd2+Wtm+8MnvYBpHdhQ+6M0zd2EsLu2x0NvcLGglIENAgMBAAECgYAsR/ZXRfJOOi1/9rOvSdLR+7bt6fL/M4crCqxHyQdEyn54t4OQoFZKG9eSqyAQ7QPPe4wA8orWuoBNqCZeNYP4pXV2ayPwZcUSN9SX4/ce5QZkhHDVBwC8SIQQ7osU6Joh4gR3I+CHlmM1dCItBizOC0Jw4Scs7cpnzzMgYhdPoQJBAO9gzFvGBROOMwtqmOU7adbbM8FE8LRHnRrKv6OvX3Qs5Kqu4vFY78LW4tPzxbzAdEMAF9rltPcc3Y9D8U8Am7UCQQCg+0Q/Za+HQ5Tgbv9QGYI1tvTUe6WiC3VHcUGmQIqa78baEd7pndcPZuqbnAPVw4oWsuhQEXSakuL+KLGJXZb5AkBE2sANidj99gIiv4e5MCzSe3zYk970zECZa0ZSa+h1/0/K9MEckOtuTOcz9kOjdmw6tXUnJrm19tyYEAACLHedAkAyrATmg8aFqFMzdhzthKoE6GsWezk+0aZ/73l/sG8wp+sK93cYSDPKyFVu1+QpJFzSGkyf726pvTSwVfTUTV5ZAkBWX+yR7VdY3e55rQBQg8k0XhFcldbaN1rZz+a41+smvpxwlslxI+ERH1yY2COUxoZIiD9VhGWudvjca+0tRgXA"; String inputStr = "sign"; byte[] data = inputStr.getBytes(); byte[] encodedData = RsaUtilClient.encryptByPrivateKey(data, privateKey); String con = "F41sMcJ0umNgZcFzxIzoLY8eZP8vwE5QNq/slHOuft63bWZwANaK8bvHNtac7/qvohEeP2BBPb80wYtToJGSsUegPu2fIlWoyA+JBVDNHRItJNwwNCgbhnBkUR2T8NGRrpjLHoA8dmAh0l9uaoCDog5ZwvHEOLSzTILvY4Rei2U=gB15njJfeQqbNJe2qQ3ui6J88vyjHDL4FKw3KWbY2iXyQM/b+RqT9kgnb0nDhAuZkJ5BWTQorpmyiAQYHaQmz5JgDpZCyw8E4XOXPgZXKgLXkEXwLlhwOhhoH5QsqCieqzu2pG6CcGeYycU+yy2fSs1VPRNIfPpeHde76ZH3urg=YRw5Y0abdEmoaLk0iz44nOPxrO4qBrIBvtBTeAQWv5Dme6YFXOxNIFd63FpE0o5c3nplueDJF17bNbIVT+rAkb54mR/jRXygvosach2ONlM/kw6UaV5lQ+BAAt/+71I7wGqxTvyxz1UFWmIIiYszQxxWIhUxH3hYXY7uHTVOg18=MMLZEy3iNkhZiPuEoLcjRKgVB6HnEY9ywVffY3B/ZBQhUqrONwkjfoh8k5w+xhT7VhMStKCxgfzNNRmKCxvxlLY86nGkZ9l9pkGJqfCQwJSNSP1eYszafgtoOn6/Rc7znPoxxhJ0AWmlcUEB+8PnePO9ApAKai0Jdx4KbpbC7Fg="; // byte[] decodedData = RSACode.decryptByPrivateKey(Base64Utils.decode(con.getBytes()), privateKey); String result = RsaUtilClient.jsencryptDecryptByPrivateKeyLong(con, privateKey); // String outputStr = new String(decodedData); // outputStr = URLDecoder.decode(outputStr); System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + result); System.err.println("私钥签名——公钥验证签名"); // 产生签名 String sign = RsaUtilClient.sign(encodedData, privateKey); System.err.println("签名:" + sign); // 验证签名 boolean status = RsaUtilClient.verify(encodedData, publicKey, sign); System.err.println("状态:" + status); } }

            RsaTestController 分发公钥和利用私钥解密的controller

            如何编写示例代码实现Java后端对接前端jsencrypt.js加密数据的解密过程?

            package com.example.oracles.controller; import com.example.oracles.utils.AjaxResult; import com.example.oracles.utils.RsaUtilClient; import org.springframework.web.bind.annotation.*; import java.security.Key; import java.util.Map; /** * @author compass * @date 2022-09-01 * @since 1.0 **/ @CrossOrigin @RestController @RequestMapping("/rsa") public class RsaTestController { /** * 获取公钥 * @return com.example.oracles.utils.AjaxResult * @author compass * @date 2022/9/1 20:01 * @since 1.0.0 **/ @GetMapping("/getPublicKey") public AjaxResult getPublicKey() { Map<String, Key> keyMap = RsaUtilClient.initKeyOnce(); String publicKey = RsaUtilClient.getPublicKey(keyMap); AjaxResult<String> ajaxResult = new AjaxResult<>("获取公钥成功", publicKey); return ajaxResult; } /** * 使用私钥进行解密 * @param params {content:"加密内容"} * @return com.example.oracles.utils.AjaxResult * @author compass * @date 2022/9/1 20:01 * @since 1.0.0 **/ @PostMapping("/privateKeyDecode") public AjaxResult privateKeyDecode(@RequestBody Map<String,String> params){ Map<String, Key> keyMap = RsaUtilClient.initKeyOnce(); String privateKey = RsaUtilClient.getPrivateKey(keyMap); String content = params.get("content"); try { String decrypt = RsaUtilClient.jsencryptDecryptByPrivateKeyLong(content, privateKey); return new AjaxResult<>("解密成功",decrypt); }catch (Exception e){ e.printStackTrace(); return new AjaxResult<>("解密失败"); } } }

            AjaxResult 请求响应工具类

            package com.example.oracles.utils; import java.io.Serializable; public class AjaxResult<T> implements Serializable { private static final long serialVersionUID = 6715651583113612048L; public static final int SUCCESS = 200; public static final int ERROR = 500; public static final int SYSTEM_ERROR = -1; public static final String SUCCESS_MESSAGE = "请求成功"; public static final String NONE_PERMISSION_MESSAGE = "权限不足,请联系管理员"; public static final String ERROR_MESSAGE = "系统异常,请联系管理员"; /** * 代码 */ private int code; /** * 错误代码 */ private String errCode; /** * 信息 */ private String msg; /** * 内容 */ private T content; public AjaxResult() { super(); this.code = SUCCESS; } public AjaxResult(String msg) { super(); this.code = ERROR; this.msg = msg; } public AjaxResult(T content) { super(); this.code = SUCCESS; this.msg = SUCCESS_MESSAGE; this.content = content; } public AjaxResult(int code, String msg, T content) { super(); this.code = code; this.msg = msg; this.content = content; } public AjaxResult(int code, String msg) { super(); this.code = code; this.msg = msg; } public AjaxResult(String msg, T content) { super(); this.code = SUCCESS; this.msg = msg; this.content = content; } public AjaxResult(int code, String errCode, String msg, T content) { super(); this.code = code; this.errCode = errCode; this.msg = msg; this.content = content; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getContent() { return content; } public void setResult(T data) { this.content = data; } }

            以上就是Java实现前端jsencrypt.js加密后端解密的示例代码的详细内容,更多关于Java前端加密 后端解密的资料请关注自由互联其它相关文章!

            本文共计3854个文字,预计阅读时间需要16分钟。

            如何编写示例代码实现Java后端对接前端jsencrypt.js加密数据的解密过程?

            目录

            1.什么是RSA

            2.RSA算法

            2.1 生成公钥和私钥 2.2 使用公钥加密信息 2.3 使用私钥解密信息

            3.RSA的应用

            3.1 数字签名

            4.RSA的安全性

            5.为什么写这篇文章

            6.前端代码

            7.后端代码

            1.什么是RSA

            计算机加密算法RSA是一种广泛使用的公钥加密技术。

            目录
            • 1.什么是RSA
            • 2.RSA算法
              • 2.1 生成公钥和私钥
              • 2.2 使用公钥加密信息
              • 2.3 使用私钥解密信息
            • 4.RSA的应用:数字签名
              • 5.RSA的安全性
                • 6.为什么要写这文章
                  • 7.前端代码
                    • 8.后端代码

                      1.什么是RSA

                      计算机中常用的加密技术分为两类:对称加密、非对称加密。

                      RSA属于非对称加密。加密、解密过程使用不同的秘钥,分为公钥、私钥。公钥可以公开,私钥不可以。

                      对称加密:加密和解密使用相同的的秘钥Key,这个Key需要在网络上传输,不安全,因此需要非对称加密。

                      2.RSA算法

                      2.1 生成公钥和私钥

                      (1)随意选择两个大的素数P和Q,P不等于Q;

                      (2)令 N = P × Q 、 T = ( P − 1 ) × ( Q − 1 ) N = P \times Q、T = (P - 1) \times (Q - 1) N=P×Q、T=(P−1)×(Q−1);

                      (3)选择一个整数E作为秘钥,需要满足:gcd(E, T)=1 && E<T;

                      (4)根据 ( D × E ) m o d T = 1 (D \times E) \ mod \ T = 1 (D×E) mod T=1,计算出D,作为另一个秘钥;

                      (5)使用PK=(N、E)作为公钥、SK=(N, D)作为私钥(当然可以反过来)。

                      2.2 使用公钥加密信息

                      使用PK=(N、E)公钥加密信息。

                      若明文为M,则密文C可以按照如下计算得到(要求M<N)

                      2.3 使用私钥解密信息

                      使用SK=(N, D)私钥解密信息。

                      如密文为C,则明文M可以按照如下计算得到:

                      4.RSA的应用:数字签名

                      数字签名是实现安全交易的核心技术之一,实现基础是RSA加密技术。

                      数字签名类似于我们生活中的手写签名,必须保证签名的人事后不能抵赖,同时不能让别人伪造我们的签名。因此数字签名需要保证:

                      (1)发送者事后不能抵赖对报文的签名;

                      (2)接受者不能伪造对报文的签名。

                      如果A向B发送报文M,A手中有私钥,公钥是公开的,A给M使用私钥进行加密再发给B即可。

                      这样即可保证上述两点:

                      (1)因为只有A可以对M使用私钥进行加密,A不能抵赖;

                      (2)B用公钥可以得到原始信息M,如果伪造成M’,则A可以证明其伪造了信息。

                      在解密之前我们先进行验签操作,如果验签失败,则认为内容是伪造,不进行解密。

                      5.RSA的安全性

                      RSA算法的安全性依赖于大数分解。因此为了保证安全性,需要使得P、Q非常大。

                      因为数据很大,又牵涉到幂次运算,因此计算量很大。

                      6.为什么要写这文章

                      因为我想做一个数据加密,就开始了解Rsa加密算法,实现一个前端加密,后端解密的一个过程,然后我也不想重复造轮子,就上百度搜索,发现好多文章都是抄来抄去去的根本不合适。所以只好自己写了一个记录,以便到时候要用的时候再看,前端使用jsencrypt.js进行加密,然后在使用的时候我发现这个内容过长无法加密,然后又找了个扩展的,可以使用长内容加密,但是到后台解密的时候出问题了,无法解密出正确内容,我只好换回原理的版本,然后自己重写了两个方法来进行扩展,实现长内容加密。这个改进后的方法按理论可以进行很大文本文本加密传输,但是具体能承载多长我没有测试过,尽量不要使用rsa加密来加密比较长的文本,因为rsa加密是比较麻烦的,复杂度比较高,在加密之前也要考虑那些数据需要加密,那些数据不需要加密,不要通通都加密,这样解密的时候会浪费许多时间,增加服务器的压力,访问时间过长。

                      因为Rsa加密算法还是稍微复杂,我就不过的阐述,直接看源码吧,先复制过去能跑,然后再自己上网搜索,相关内容进行脑补,这个改进估计会存在问题,因为加密的长度限制117,和每次加密后的内容长度172 ,我不太清楚是不是固定的,我尝试了很多次都没有出现问题,等出现问题再解决吧。

                      7.前端代码

                      <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <script src="../js/jsencrypt.js" type="text/javascript" charset="utf-8"></script> <script src="../js/jquery1.42.min.js" type="text/javascript" charset="utf-8"></script> <body> <script type="text/javascript"> /** * 对加密工具进行封装 */ let RsaUtil = { publicKey: '', privateKey: '', rsaEncrypt: {}, // 长文本加密 encryptLong: function(content) { let encryptionSectionSize = 117; content = encodeURIComponent(content); let ciphertext = ''; if (content && content.length > encryptionSectionSize) { let paragraphic = content.length / encryptionSectionSize; let isIntger = (paragraphic | 0) === paragraphic; let encryptionCountet = parseInt(paragraphic); if (isIntger) { for (let i = 0; i < encryptionCountet; i++) { ciphertext += this.rsaEncrypt.encrypt(content.substring(i * encryptionSectionSize, (i * encryptionSectionSize) + encryptionSectionSize)); } } else { let lastContentLength = content.length % encryptionSectionSize; for (let i = 0; i < encryptionCountet; i++) { ciphertext += this.rsaEncrypt.encrypt(content.substring(i * encryptionSectionSize, (i * encryptionSectionSize) + encryptionSectionSize)); } ciphertext += this.rsaEncrypt.encrypt(content.substring(encryptionCountet * encryptionSectionSize, encryptionCountet * encryptionSectionSize + lastContentLength)); } } else { ciphertext = this.rsaEncrypt.encrypt(content); } return ciphertext; }, // 长文本解密 decryptLong: function(content) { let decodeSectionSize = 172; let decodeText = ''; let isFinish = false; if (content && content.length > decodeSectionSize) { let paragraphic = content.length / decodeSectionSize; let isIntger = (paragraphic | 0) === paragraphic; let encryptionCountet = parseInt(paragraphic); if (isIntger) { for (let i = 0; i < encryptionCountet; i++) { decodeText += this.rsaEncrypt.decrypt(content.substring(i * decodeSectionSize, (i * decodeSectionSize) + decodeSectionSize)); isFinish = decodeText.indexOf('false') !== -1; if (isFinish) { return isFinish; } } } else { let lastContentLength = content.length % decodeSectionSize; for (let i = 0; i < encryptionCountet; i++) { decodeText += this.rsaEncrypt.encrypt(content.substring(i * decodeSectionSize, (i * decodeSectionSize) + decodeSectionSize)); isFinish = decodeText.indexOf('false') !== -1; if (isFinish) { return isFinish; } } decodeText += this.rsaEncrypt.encrypt(content.substring(encryptionCountet * decodeSectionSize, encryptionCountet * decodeSectionSize + lastContentLength)); } } else { decodeText = this.rsaEncrypt.decrypt(content); } return decodeURIComponent(decodeText); }, // 小于117长度的字符串加密 encrypt: function(content) { return this.encrypt(content); }, // 小于117长度的字符串解密 decrypt: function(content) { return this.decrypt(content); }, // 初始化RsaUtil工具对象 init: function(publicKey, privateKey) { if (!publicKey) { throw new Error('publicKey cant't null'); } let rsaEncrypt = new JSEncrypt(); rsaEncrypt.setPublicKey(publicKey); if (privateKey) { rsaEncrypt.setPrivateKey(privateKey); } this.publicKey = publicKey; this.privateKey = privateKey; this.rsaEncrypt = rsaEncrypt; } } async function getPublicKey() { return new Promise((resolve, reject) => { $.ajax({ url: "localhost:8080/rsa/getPublicKey", type: "GET", data: {}, success: function(data, textStatus) { if (data && data.code === 200 && data.content.length > 0) { resolve(data.content); } else { reject(false); } }, error: function(error) { reject(false); } }); }) } async function privateKeyDecode(content) { return new Promise((resolve, reject) => { $.ajax({ url: "localhost:8080/rsa/privateKeyDecode", type: "POST", contentType: "application/json", dataType: "json", data: JSON.stringify({ content }), success: function(data, textStatus) { if (data && data.code === 200 && data.content.length > 0) { resolve(data.content); } else { resolve(false); } }, error: function(error) { resolve(false); } }); }) } let userInfo = { id: '1564868915154190336', nickName: '小明', sex: '男', email: '1482334546@qq.com', userType: '1', userName: 'admin', password: 'admin666?', createTime: '2022-08-31 14:55', valid: '1', isDelete: '0', headImg: 'profile.csdnimg.cn/7/3/0/2_m0_46188681', } let userInfoStr = JSON.stringify(userInfo) async function dataEncryption() { let publicKey = await getPublicKey(); RsaUtil.init(publicKey); console.log("后台获取到的公钥:" + publicKey) let ciphertext = RsaUtil.encryptLong(userInfoStr); console.log("使用后台公钥加密后的文本:" + ciphertext); let decodeResult = await privateKeyDecode(ciphertext); console.log("使用后台私钥解密后的文本:" + decodeResult) console.log("是否解密成功",decodeResult === userInfoStr) } dataEncryption(); </script> </body> </html>

                      8.后端代码

                      RsaUtilClient配合 jsencrypt.js 解密的工具类

                      import org.springframework.util.Base64Utils; import javax.crypto.Cipher; import java.net.URLDecoder; import java.security.*; import java.security.spec.*; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class RsaUtilClient { 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"; private static volatile ConcurrentHashMap<String,Key> KEY_MAP = new ConcurrentHashMap<>(2); /** * base64解码 * * @param content * @return byte[] * @author compass * @date 2022/9/1 17:12 * @since 1.0.0 **/ public static byte[] decryptBASE64(String content) { return org.springframework.util.Base64Utils.decode(content.getBytes()); } /** * base64编码 * * @param bytes 字符byte数组 * @return java.lang.String * @author compass * @date 2022/9/1 17:12 * @since 1.0.0 **/ public static String encryptBASE64(byte[] bytes) { return new String(org.springframework.util.Base64Utils.encode(bytes)); } /** * 用私钥对信息生成数字签名 * * @param data 加密数据 * @param privateKey 私钥 * @return java.lang.String * @author compass * @date 2022/9/1 14:21 * @since 1.0.0 **/ 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)); } /** * 通过私钥解密 * * @param data 加密的byte数组 * @param privateKey 私钥 * @return byte[] * @author compass * @date 2022/9/1 17:14 * @since 1.0.0 **/ public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(privateKey); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privatizationKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privatizationKey); return cipher.doFinal(data); } /** * 私钥解密前端jsencrypt分段加密的长文本内容, * 前端加密的字符串需要使用encodeURIComponent编码,后端使用URLDecoder.decode解码来解决中文字符串无法解密的问题 * * @param content 加密的内容 * @param privateKey 私钥 * @return java.lang.String * @author compass * @date 2022/9/1 16:53 * @since 1.0.0 **/ public static String jsencryptDecryptByPrivateKeyLong(String content, String privateKey) { String resultContent = ""; try { StringBuffer buffer = new StringBuffer(); if (content != null && content.trim().length() > 0) { String[] contentList = content.split("="); for (String item : contentList) { byte[] itemBytes = Base64Utils.decode((item + "=").getBytes()); try { byte[] itemResultBytes = decryptByPrivateKey(itemBytes, privateKey); String itemResultStr = new String(itemResultBytes); buffer.append(itemResultStr); } catch (Exception e) { e.printStackTrace(); } } } resultContent = URLDecoder.decode(buffer.toString()); } catch (Exception e) { e.printStackTrace(); System.err.println("jsencryptDecryptByPrivateKeyLong解密出错:" + e.getMessage() + ":" + "解密内容:" + content); throw new RuntimeException("rsa解密失败"); } return resultContent; } /** * 通过私钥解密 * * @param data 加密的byte数组 * @param privateKey 私钥 * @return byte[] * @author compass * @date 2022/9/1 17:14 * @since 1.0.0 **/ public static byte[] decryptByPrivateKey(String data, String privateKey) throws Exception { return decryptByPrivateKey(decryptBASE64(data), privateKey); } /** * 解密<br> * * * @param data * @param key * @return * @throws Exception */ /** * 用公钥解密 * * @param data 代解密的byte数组 * @param publicKey * @return byte[] * @author compass * @date 2022/9/1 17:17 * @since 1.0.0 **/ public static byte[] decryptByPublicKey(byte[] data, String publicKey) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(publicKey); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicityKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicityKey); 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 存放私钥和公钥的map集合 * @return java.lang.String * @author compass * @date 2022/9/1 17:18 * @since 1.0.0 **/ public static String getPrivateKey(Map<String, Key> keyMap) { Key key = keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap 放私钥和公钥的map集合 * @return java.lang.String * @author compass * @date 2022/9/1 17:28 * @since 1.0.0 **/ public static String getPublicKey(Map<String, Key> keyMap) { Key key = keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化公钥和秘钥 每次调用可以获取不同的公钥和私钥 * @return java.util.Map<java.lang.String, java.security.Key> * @author compass * @date 2022/9/1 17:28 * @since 1.0.0 **/ public static ConcurrentHashMap<String, Key> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); ConcurrentHashMap<String, Key> keyMap = new ConcurrentHashMap<>(2); keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥 keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥 return keyMap; } /** * 初始化公钥和秘钥 初始化唯一的公钥和私钥 * @return java.util.Map<java.lang.String, java.security.Key> * @author compass * @date 2022/9/1 17:28 * @since 1.0.0 **/ public static Map<String,Key> initKeyOnce() { if (KEY_MAP.size() == 0){ synchronized (RsaUtilClient.class){ if (KEY_MAP.size() == 0){ try { KEY_MAP = initKey(); }catch (Exception e){ e.printStackTrace(); throw new RuntimeException("公钥和私钥初始化失败"); } } } } return KEY_MAP; } public static void main(String[] args) throws Exception { String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWh3Nyt+5QqUXw1qHXM4k7lq98f9wA4iQgKK1LB1tr4uIgL/dls0LkBgY4oS/Dn3J0qHkpUTkTT84uMHey7cwdd9k90/65cpdawX0J0KO3S3Zwl9d5AJt7/hdSap3AcHw3dvlrZvvDJ72AaR3YUPujNM3dhLC7tsdDb3CxoJSBDQIDAQAB"; String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJaHc3K37lCpRfDWodcziTuWr3x/3ADiJCAorUsHW2vi4iAv92WzQuQGBjihL8OfcnSoeSlRORNPzi4wd7LtzB132T3T/rlyl1rBfQnQo7dLdnCX13kAm3v+F1JqncBwfDd2+Wtm+8MnvYBpHdhQ+6M0zd2EsLu2x0NvcLGglIENAgMBAAECgYAsR/ZXRfJOOi1/9rOvSdLR+7bt6fL/M4crCqxHyQdEyn54t4OQoFZKG9eSqyAQ7QPPe4wA8orWuoBNqCZeNYP4pXV2ayPwZcUSN9SX4/ce5QZkhHDVBwC8SIQQ7osU6Joh4gR3I+CHlmM1dCItBizOC0Jw4Scs7cpnzzMgYhdPoQJBAO9gzFvGBROOMwtqmOU7adbbM8FE8LRHnRrKv6OvX3Qs5Kqu4vFY78LW4tPzxbzAdEMAF9rltPcc3Y9D8U8Am7UCQQCg+0Q/Za+HQ5Tgbv9QGYI1tvTUe6WiC3VHcUGmQIqa78baEd7pndcPZuqbnAPVw4oWsuhQEXSakuL+KLGJXZb5AkBE2sANidj99gIiv4e5MCzSe3zYk970zECZa0ZSa+h1/0/K9MEckOtuTOcz9kOjdmw6tXUnJrm19tyYEAACLHedAkAyrATmg8aFqFMzdhzthKoE6GsWezk+0aZ/73l/sG8wp+sK93cYSDPKyFVu1+QpJFzSGkyf726pvTSwVfTUTV5ZAkBWX+yR7VdY3e55rQBQg8k0XhFcldbaN1rZz+a41+smvpxwlslxI+ERH1yY2COUxoZIiD9VhGWudvjca+0tRgXA"; String inputStr = "sign"; byte[] data = inputStr.getBytes(); byte[] encodedData = RsaUtilClient.encryptByPrivateKey(data, privateKey); String con = "F41sMcJ0umNgZcFzxIzoLY8eZP8vwE5QNq/slHOuft63bWZwANaK8bvHNtac7/qvohEeP2BBPb80wYtToJGSsUegPu2fIlWoyA+JBVDNHRItJNwwNCgbhnBkUR2T8NGRrpjLHoA8dmAh0l9uaoCDog5ZwvHEOLSzTILvY4Rei2U=gB15njJfeQqbNJe2qQ3ui6J88vyjHDL4FKw3KWbY2iXyQM/b+RqT9kgnb0nDhAuZkJ5BWTQorpmyiAQYHaQmz5JgDpZCyw8E4XOXPgZXKgLXkEXwLlhwOhhoH5QsqCieqzu2pG6CcGeYycU+yy2fSs1VPRNIfPpeHde76ZH3urg=YRw5Y0abdEmoaLk0iz44nOPxrO4qBrIBvtBTeAQWv5Dme6YFXOxNIFd63FpE0o5c3nplueDJF17bNbIVT+rAkb54mR/jRXygvosach2ONlM/kw6UaV5lQ+BAAt/+71I7wGqxTvyxz1UFWmIIiYszQxxWIhUxH3hYXY7uHTVOg18=MMLZEy3iNkhZiPuEoLcjRKgVB6HnEY9ywVffY3B/ZBQhUqrONwkjfoh8k5w+xhT7VhMStKCxgfzNNRmKCxvxlLY86nGkZ9l9pkGJqfCQwJSNSP1eYszafgtoOn6/Rc7znPoxxhJ0AWmlcUEB+8PnePO9ApAKai0Jdx4KbpbC7Fg="; // byte[] decodedData = RSACode.decryptByPrivateKey(Base64Utils.decode(con.getBytes()), privateKey); String result = RsaUtilClient.jsencryptDecryptByPrivateKeyLong(con, privateKey); // String outputStr = new String(decodedData); // outputStr = URLDecoder.decode(outputStr); System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + result); System.err.println("私钥签名——公钥验证签名"); // 产生签名 String sign = RsaUtilClient.sign(encodedData, privateKey); System.err.println("签名:" + sign); // 验证签名 boolean status = RsaUtilClient.verify(encodedData, publicKey, sign); System.err.println("状态:" + status); } }

                      RsaTestController 分发公钥和利用私钥解密的controller

                      如何编写示例代码实现Java后端对接前端jsencrypt.js加密数据的解密过程?

                      package com.example.oracles.controller; import com.example.oracles.utils.AjaxResult; import com.example.oracles.utils.RsaUtilClient; import org.springframework.web.bind.annotation.*; import java.security.Key; import java.util.Map; /** * @author compass * @date 2022-09-01 * @since 1.0 **/ @CrossOrigin @RestController @RequestMapping("/rsa") public class RsaTestController { /** * 获取公钥 * @return com.example.oracles.utils.AjaxResult * @author compass * @date 2022/9/1 20:01 * @since 1.0.0 **/ @GetMapping("/getPublicKey") public AjaxResult getPublicKey() { Map<String, Key> keyMap = RsaUtilClient.initKeyOnce(); String publicKey = RsaUtilClient.getPublicKey(keyMap); AjaxResult<String> ajaxResult = new AjaxResult<>("获取公钥成功", publicKey); return ajaxResult; } /** * 使用私钥进行解密 * @param params {content:"加密内容"} * @return com.example.oracles.utils.AjaxResult * @author compass * @date 2022/9/1 20:01 * @since 1.0.0 **/ @PostMapping("/privateKeyDecode") public AjaxResult privateKeyDecode(@RequestBody Map<String,String> params){ Map<String, Key> keyMap = RsaUtilClient.initKeyOnce(); String privateKey = RsaUtilClient.getPrivateKey(keyMap); String content = params.get("content"); try { String decrypt = RsaUtilClient.jsencryptDecryptByPrivateKeyLong(content, privateKey); return new AjaxResult<>("解密成功",decrypt); }catch (Exception e){ e.printStackTrace(); return new AjaxResult<>("解密失败"); } } }

                      AjaxResult 请求响应工具类

                      package com.example.oracles.utils; import java.io.Serializable; public class AjaxResult<T> implements Serializable { private static final long serialVersionUID = 6715651583113612048L; public static final int SUCCESS = 200; public static final int ERROR = 500; public static final int SYSTEM_ERROR = -1; public static final String SUCCESS_MESSAGE = "请求成功"; public static final String NONE_PERMISSION_MESSAGE = "权限不足,请联系管理员"; public static final String ERROR_MESSAGE = "系统异常,请联系管理员"; /** * 代码 */ private int code; /** * 错误代码 */ private String errCode; /** * 信息 */ private String msg; /** * 内容 */ private T content; public AjaxResult() { super(); this.code = SUCCESS; } public AjaxResult(String msg) { super(); this.code = ERROR; this.msg = msg; } public AjaxResult(T content) { super(); this.code = SUCCESS; this.msg = SUCCESS_MESSAGE; this.content = content; } public AjaxResult(int code, String msg, T content) { super(); this.code = code; this.msg = msg; this.content = content; } public AjaxResult(int code, String msg) { super(); this.code = code; this.msg = msg; } public AjaxResult(String msg, T content) { super(); this.code = SUCCESS; this.msg = msg; this.content = content; } public AjaxResult(int code, String errCode, String msg, T content) { super(); this.code = code; this.errCode = errCode; this.msg = msg; this.content = content; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getContent() { return content; } public void setResult(T data) { this.content = data; } }

                      以上就是Java实现前端jsencrypt.js加密后端解密的示例代码的详细内容,更多关于Java前端加密 后端解密的资料请关注自由互联其它相关文章!