AES加解密 - Java和Node互通版本
一. Java 版本
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @Date 2023/4/10 14:49
* @Created by jj.lin
*/
public class Test {
/**
* 密钥 256位32个字节
*/
private static final String key = "49306136985386814874058301261917";
/**
* 初始向量 128位16个字节
*/
private static final String iv = "5582000767806042";
/**
* 加密解密算法/加密模式/填充方式
*/
private static final String cipher_algorithm = "AES/CBC/PKCS5Padding";
/**
* 加解密算法
*/
private static final String algorithm = "AES";
/**
* 字符集
*/
private static final String charset = "UTF-8";
public static String encode(String content) {
try {
SecretKey secretKey = new SecretKeySpec(key.getBytes(), algorithm);
Cipher cipher = Cipher.getInstance(cipher_algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv.getBytes()));
byte[] byteEncode = content.getBytes(charset);
// 根据密码器的初始化方式加密
byte[] byteAES = cipher.doFinal(byteEncode);
// 将加密后的数据编码为字符串
return Hex.encodeHexString(byteAES);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* AES解密
*/
public static String decode(String content) {
try {
SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), algorithm);
Cipher cipher = Cipher.getInstance(cipher_algorithm);
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv.getBytes()));
// 将加密并编码后的内容解码成字节数组
byte[] byteContent = Hex.decodeHex(content.toCharArray());
// 解密
byte[] byteDecode = cipher.doFinal(byteContent);
return new String(byteDecode, charset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String str = "LJJ:SHA:19990915";
// 加密
String str1 = encode(str);
System.out.println("加密后:" + str1);
// 解密
String str2 = decode(str1);
System.out.println("解密后:" + str2);
}
}
结果如下:
二. Node 版本
首先安装:crypto
npm i crypto
上代码:
const crypto = require('crypto');
/** 加解密方式 */
const algorithm = 'aes-256-cbc';
/** 密钥 256位 32字节 */
const key = '49306136985386814874058301261917';
/** 初始向量 16字节*/
const iv = '5582000767806042';
/** 字符集 */
const charset = 'utf8';
/** 编码方式 */
const cipherEncoding = 'hex';
/**
* 加密
*/
function encrypt(str) {
let cipher = crypto.createCipheriv(algorithm, key, iv);
let crypted = cipher.update(str, charset, cipherEncoding);
crypted += cipher.final(cipherEncoding);
crypted = crypted.replace(/\+/g, '%2b')
return crypted
}
/**
* 解密
*/
function decrypt(str) {
str = str.replace(/(%2b)/g, '+')
let cipher = crypto.createDecipheriv(algorithm, key, iv);
const decrypted = cipher.update(str, cipherEncoding, charset);
let result = decrypted + cipher.final(charset);
return result
}
const str = 'LJJ:SHA:19990915'
const e = encrypt(str)
console.log(`加密后:${e}`)
const dd = decrypt(e)
console.log(`解密后:${dd}`)
const d = decrypt('3560d58b2a89da591a3ac2bc56aefe566d1f257c1f2a2d788a45a47e67002d54')
console.log(`(Java)解密后:${d}`)
结果如下:
附:随机生成指定位数的字符串
这个可以用来作为秘钥和偏移量的随机生成工具
function generateRandomKey(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
const key = generateRandomKey(32);
console.log(key);