• jsencrypt.js加密java后端解密


    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

    (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

    image-20220901213136371

    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: "http://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: "http://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: 'https://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>
    
     
    
    
    • 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

    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);
        }
    
        /**
         * 解密
    * * * @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); } /** * 加密
    * 用公钥加密 * * @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()); } /** * 加密
    * 用私钥加密 * * @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 * @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 * @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); } }
    • 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
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344

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

    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<>("解密失败");
            }
    
        }
    }
    
    
    • 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

    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;
    	}
    	
    }
    
    • 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

    完整代码我已经贴出来: 如果需要 jsencrypt.js 可以百度自行下载,也可以在我的资源里面下载全部源代码,下载链接:https://download.csdn.net/download/m0_46188681/86506578

    后续再讲Rsa和Aes组合使用,因为最近比较忙这篇文章也讲的比较少,后续会专门补上,完完整整的把这个描述清楚,不喜勿喷,自己划走便是,有些注意点我已经写在代码注释中,就不过多赘述。

  • 相关阅读:
    springboot常用注释
    1086 简单数字打印
    汇编语言中断编程步骤
    软件测试工程师必备的SQL语句基础
    Linux学习——文件IO
    笔试强训第一天
    记一堂公开课《前端架构的设计与进化》思考总结
    MobPush丨 iOS端快速集成方法
    Kubernetes学习记录之Pod
    rpc的仅有通信的功能,在网断的情况下,比网通情况下,内存增长会是什么原因
  • 原文地址:https://blog.csdn.net/m0_46188681/article/details/126652457