java+加密+解密+split_AES+RSA加密解密(js和java互通)

本文详细介绍了如何使用JavaScript和Java进行数据的AES和RSA加解密,包括客户端生成AES密钥、转换为Base64、使用RSA公钥加密,以及服务端使用私钥解密AES密钥,再进行AES解密的过程。整个流程确保了客户端与服务端数据的安全传输。
摘要由CSDN通过智能技术生成

客戶端和服務端數據加解密流程圖

09360de7357acadf0290140f27df26fb.png

案例

1、客戶端生成aes秘鑰

jsfunction getAesKey(len) {

len = len || 32;

var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默認去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/

var maxPos = $chars.length;

var keyStr = '';

for(i = 0; i < len; i++) {

keyStr += $chars.charAt(Math.floor(Math.random() * maxPos));

}

return keyStr;

}

2、客戶端生成公鑰

jsvar pubKey = new RSAKeyPair(public_exponent, "", modulus);

//生成公鑰,這里的public_exponent和modulus是從服務端獲取,便於服務端可以定時更新公鑰

3、 客戶端aesKey轉成base64

jsvar keyStr64=encode64(keyStr);

4、客戶端生成RSA公鑰

jssetMaxDigits(130);//BigInt.js

var pubKey = new RSAKeyPair(public_exponent, "", modulus); //獲得rsa公鑰

5、用公鑰加密AES密鑰

jsvar aesKeyMi = encryptedString(pubKey, keyStr64, RSAAPP.NoPadding, RSAAPP.NumericEncoding);

//此處的keyStr64是AES密鑰轉成base64后的值

6、用客戶端生成的AES密鑰加密入參

jsvar msg_source = "0102030405060708";

//此處的iv向量和服務端保持一致

var iv = CryptoJS.enc.Utf8.parse(msg_source);

tool.encrypt = function(data) {

//AES加密

var key = CryptoJS.enc.Utf8.parse(keyStr);

var srcs = CryptoJS.enc.Utf8.parse(data);

var encrypted = CryptoJS.AES.encrypt(srcs, key, {

iv: iv,

mode: CryptoJS.mode.CBC

});

return encrypted;

}

7、客戶端的入參形式{"key":aesKeyMi,"param":"此處為加密后的參數"}

8、服務端獲取AES密鑰

java/**

* 私鑰解密

*

*@param key 接口入參的key

*@return

*@throws Exception

*/

public static String getKey(String key) throws Exception {

//獲取經過rsa非對稱加密的 客戶端生成的aes密鑰

if(StringUtils.nullOrBlank(key)) {

return "";

}

RSAPrivateKey privateKey = null;

try {

String privateExponentStr = ENVUtils.getPrivateExponent();//本案例中的privateExponentStr通過配置文件設置

String modulusStr = ENVUtils.getModulus();//本案例中的modulusStr通過配置文件設置

BigInteger modulus = new BigInteger(new String(Base64.decodeBase64(modulusStr), "UTF-8"), 16);

BigInteger privateExponent = new BigInteger(new String(Base64.decodeBase64(privateExponentStr), "UTF-8"), 16);

privateKey = RSAUtils.getPrivateKey(modulus, privateExponent);

return RSAUtils.decryptByPrivateKey(key, privateKey);

}catch(Exception e) {

logger.error("獲取私鑰失敗", e);

return "";

}

}

RSAUtils相關代碼public static RSAPrivateKey getPrivateKey(BigInteger modulus, BigInteger exponent) {

try {

KeyFactory keyFactory = KeyFactory.getInstance("RSA", RSA_RPOVIDER);

RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, exponent);

return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);

} catch (Exception e) {

logger.error("合成私鑰異常", e);

return null;

}

}

/**

* 私鑰解密

*

*@param data

*@param privateKey 私鑰

*@return

*@throws Exception

*/

public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception {

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", RSA_RPOVIDER);

cipher.init(Cipher.DECRYPT_MODE, privateKey);

// 模長

int key_len = privateKey.getModulus().bitLength() / 8;

byte[] b = StringUtils.decodeHex(data);

// 如果密文長度大於模長則要分組解密

String ming = "";

byte[][] arrays = splitArray(b, key_len);

for (byte[] arr : arrays) {

ming += new String(cipher.doFinal(arr));

}

return ming;

}

9、服務端用AES密鑰解密入參param、

javapublic static String aesDecrypt(String encryptStr, String decryptKey)

throws Exception {

if(StringUtils.nullOrBlank(decryptKey)) {

return encryptStr;

}

return aesDecryptByBytes(

base64Decode(encryptStr), decryptKey);

}

public static String aesDecryptByBytes(byte[] encryptBytes,

String decryptKey) throws Exception {

byte[] keys = base64Decode(decryptKey);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//此處的部位方式應該跟客戶端保持一致CryptoJS.mode.CBC

IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());//此處的向量應該跟客戶端保持一致0102030405060708

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keys, "AES"), iv);

byte[] decryptBytes = cipher.doFinal(encryptBytes);

return new String(decryptBytes, "utf-8");

}

public static byte[] base64Decode(String base64Code) throws Exception {

return base64Code == null ? null : Base64.decodeBase64(base64Code);

}

10、服務端處理完業務后,返回加密的數據

javapublic static String aesEncrypt(String content, String encryptKey)

throws Exception {

if(StringUtils.nullOrBlank(encryptKey)) {

return content;

}

return base64Encode(aesEncryptToBytes(content, encryptKey));

}

public static byte[] aesEncryptToBytes(String content, String encryptKey)

throws Exception {

byte[] keys = base64Decode(encryptKey);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//此處的部位方式應該跟客戶端保持一致CryptoJS.mode.CBC

IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());//此處的向量應該跟客戶端保持一致0102030405060708

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keys, "AES"), iv);

return cipher.doFinal(content.getBytes("utf-8"));

}

public static String base64Encode(byte[] bytes) {

return Base64.encodeBase64String(bytes);

}

11、客戶端解密出參dataMi

js//AES解密

var msg_source = "0102030405060708";

//此處的iv向量和服務端保持一致

var iv = CryptoJS.enc.Utf8.parse(msg_source);

tool.decrypt = function(data) {

var key = CryptoJS.enc.Utf8.parse(aesKey);

var decrypt = CryptoJS.AES.decrypt(data, key, {

iv: iv,

mode: CryptoJS.mode.CBC

});

var rtnStr = CryptoJS.enc.Utf8.stringify(decrypt).toString();

mConsole("11111" + rtnStr);

return rtnStr;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,在你的 Maven 项目中添加以下依赖项: ```xml <dependencies> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.14</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.68</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.68</version> </dependency> </dependencies> ``` 其中,`commons-codec` 用于 Base64 编码,`bcprov-jdk15on` 和 `bcpkix-jdk15on` 用于 RSA 加密解密。 接下来,生成 RSA 密钥对: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; public class RSAUtil { public static KeyPair generateKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(2048); return generator.generateKeyPair(); } } ``` 然后,使用公钥加密和私钥解密: ```java import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; public class RSAUtil { static { Security.addProvider(new BouncyCastleProvider()); } public static String encrypt(String data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(data.getBytes()); return new String(Base64.encode(encryptedBytes), "UTF-8"); } public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] encryptedBytes = Base64.decode(encryptedData.getBytes("UTF-8")); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes); } } ``` 最后,使用 `split` 方法对加密后的字符串进行分段: ```java import org.apache.commons.lang3.StringUtils; public class RSAUtil { public static String encrypt(String data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(data.getBytes()); String encryptedStr = new String(Base64.encode(encryptedBytes), "UTF-8"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < encryptedStr.length(); i += 100) { sb.append(StringUtils.substring(encryptedStr, i, i + 100)).append("\n"); } return sb.toString(); } } ``` 这样,就可以使用 RSA 加密解密,以及对加密后的字符串进行分段了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值