当前位置: 首页 > 工具软件 > nodejs-c4 > 使用案例 >

java nodejs aes_JAVA与NodeJS实现AES加密

常翰
2023-12-01

内容要点

本文实现java与nodejs的AES加密方式如下,并可实现java加密,nodejs解密或者nodejs加密,java解密

aes-128-ecb

aes-256-ecb

aes-128-cbc

aes-256-cbc

java实现AES

注意

Java本身限制密钥的长度最多128位,而AES256需要的密钥长度是256位,因此需要到Java官网上下载一个Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。在Java SE的下载页面下面的Additional Resources那里会有下载链接。下载后打开压缩包,里面有两个jar文件:

local_policy.jar和US_export_policy.jar

把这两个jar文件解压到JRE目录下的lib/security文件夹,覆盖原来的文件。这样Java就不再限制密钥的长度了,否则编译会报错:

java.security.InvalidKeyException: Illegal key size

import org.apache.commons.lang.StringUtils;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import java.security.spec.AlgorithmParameterSpec;

public class EncodeUtil {

public static void main(String[] args) throws Exception {

//key是16进制,需要转换为bytes,转换后bytes长度为16,即aes128,如果bytes长度是32则是aes256

//也就是说keybytes.length须满足16的整数倍

String key128 = "c4b84456c1379bec99c4d1b7e9f13173";

String key256 = "c4b84456c1379bec99c4d1b7e9f13173c4b84456c1379bec99c4d1b7e9f13173";

//iv.length须满足16的整数倍

byte[] iv = "abcdefgh12345678".getBytes("UTF-8");

String content_str = "helloworld 你好";

byte[] contentbytes = content_str.getBytes("utf-8");

//ecb128 bytes

byte[] encryptbytes = EncodeUtil.aesEncryptToECB(contentbytes,key128);

byte[] decryptbytes = EncodeUtil.aesDecryptToECB(encryptbytes,key128);

System.out.println(new String(decryptbytes,"utf-8"));

//ecb256 bytes

encryptbytes = EncodeUtil.aesEncryptToECB(contentbytes,key256);

decryptbytes = EncodeUtil.aesDecryptToECB(encryptbytes,key256);

System.out.println(new String(decryptbytes,"utf-8"));

//ecb128 String

String encryptString = EncodeUtil.aesEncryptToECB(content_str,key128);

String decryptString = EncodeUtil.aesDecryptToECB(encryptString,key128);

System.out.println(decryptString);

//ecb256 String

encryptString = EncodeUtil.aesEncryptToECB(content_str,key256);

decryptString = EncodeUtil.aesDecryptToECB(encryptString,key256);

System.out.println(decryptString);

//cbc128 bytes

encryptbytes = EncodeUtil.aesEncryptToCBC(contentbytes,key128,iv);

decryptbytes = EncodeUtil.aesDecryptToCBC(encryptbytes,key128,iv);

System.out.println(new String(decryptbytes,"utf-8"));

//cbc256 bytes

encryptbytes = EncodeUtil.aesEncryptToCBC(contentbytes,key256,iv);

decryptbytes = EncodeUtil.aesDecryptToCBC(encryptbytes,key256,iv);

System.out.println(new String(decryptbytes,"utf-8"));

//cbc128 String

encryptString = EncodeUtil.aesEncryptToCBC(content_str,key128,iv);

decryptString = EncodeUtil.aesDecryptToCBC(encryptString,key128,iv);

System.out.println(decryptString);

//cbc256 String

encryptString = EncodeUtil.aesEncryptToCBC(content_str,key256,iv);

decryptString = EncodeUtil.aesDecryptToCBC(encryptString,key256,iv);

System.out.println(decryptString);

}

/**

* base 64 encode

*

* @param bytes 待编码的byte[]

* @return 编码后的base 64 code

*/

public static String base64Encode(byte[] bytes) {

return new BASE64Encoder().encode(bytes);

}

/**

* base 64 decode

*

* @param base64Code 待解码的base 64 code

* @return 解码后的byte[]

* @throws Exception

*/

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

return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);

}

/**

* 验证密钥长度是否有效

*

* @param key 密钥bytes

* @throws Exception

*/

public static void checkkey(byte[] key) throws Exception {

if(key.length != 16 && key.length != 32) {

throw new Exception("密钥长度错误,key byte[]必须是16或者32位");

}

}

/**

* AES加密 aes-128/256-ecb

*

* @param content 待加密的内容

* @param encryptKey 加密密钥

* @return 加密后的byte[]

* @throws Exception

*/

public static byte[] aesEncryptToECB(byte[] content, String encryptKey) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(encryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

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

return cipher.doFinal(content);

}

/**

* AES加密 aes-128/256-ecb

*

* @param content 待加密的内容

* @param encryptKey 加密密钥

* @return 加密后的base64字符串

* @throws Exception

*/

public static String aesEncryptToECB(String content, String encryptKey) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(encryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

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

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

}

/**

* AES解密 aes-128/256-ecb

*

* @param content 待解密的byte[]

* @param decryptKey 解密密钥

* @return 解密后的byte[]

* @throws Exception

*/

public static byte[] aesDecryptToECB(byte[] content, String decryptKey) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(decryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

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

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

return decryptBytes;

}

/**

* AES解密 aes-128/256-ecb

*

* @param content 待解密的byte[]

* @param decryptKey 解密密钥

* @return 解密后的String

* @throws Exception

*/

public static String aesDecryptToECB(String content, String decryptKey) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(decryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

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

byte[] decryptBytes = cipher.doFinal(base64Decode(content));

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

}

/**

* AES加密 aes-128/256-cbc

*

* @param content 待解密的byte[]

* @param encryptKey 加密密钥

* @param iv 偏移

* @return 解密后的byte[]

* @throws Exception

*/

public static byte[] aesEncryptToCBC(byte[] content, String encryptKey,byte[] iv) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(encryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

//算法参数

AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"),paramSpec);

return cipher.doFinal(content);

}

/**

* AES解密 aes-128/256-cbc

*

* @param content 待解密的byte[]

* @param decryptKey 解密密钥

* @param iv 偏移

* @return 解密后的byte[]

* @throws Exception

*/

public static byte[] aesDecryptToCBC(byte[] content, String decryptKey,byte[] iv) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(decryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

//算法参数

AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),paramSpec);

return cipher.doFinal(content);

}

/**

* AES加密 aes-128/256-cbc

*

* @param content 待解密的byte[]

* @param encryptKey 加密密钥

* @param iv 偏移

* @return 解密后的byte[]

* @throws Exception

*/

public static String aesEncryptToCBC(String content, String encryptKey,byte[] iv) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(encryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

//算法参数

AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"),paramSpec);

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

}

/**

* AES解密 aes-128/256-cbc

*

* @param content 待解密的byte[]

* @param decryptKey 解密密钥

* @param iv 偏移

* @return 解密后的byte[]

* @throws Exception

*/

public static String aesDecryptToCBC(String content, String decryptKey,byte[] iv) throws Exception {

byte[] key = org.apache.commons.codec.binary.Hex.decodeHex(decryptKey.toCharArray());

checkkey(key);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

//算法参数

AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),paramSpec);

byte[] decryptBytes = cipher.doFinal(base64Decode(content));

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

}

}

nodejs

说明

以下nodejs代码来源于 aes-cross项目

/**

* "AES/cbc/pkcs5Padding" encription and decription.

* setAutoPadding(true) is actually pkcs5Padding,.

*/

'use strict';

var crypto = require('crypto');

var CBC = 'cbc';

var ECB = 'ecb';

var NULL_IV = new Buffer([]);

var IV = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

var cipherMode = ECB;

var keySize = 128;

var algorithm;

setAlgorithm();

var outputEncoding = 'base64';

var inputEncoding = 'utf8';

function setAlgorithm() {

algorithm = 'aes-' + keySize + '-' + cipherMode;

}

function setCipherMode(mode) {

if (mode !== CBC && mode !== ECB) {

throw ('AES.setCipherMode error: ' + mode);

}

cipherMode = mode;

setAlgorithm();

}

function setKeySize(size) {

if (size !== 128 && size !== 256) {

throw ('AES.setKeySize error: ' + size);

}

keySize = size;

setAlgorithm();

// console.log('setKeySize:%j',keySize);

}

/**

* the key must match the keySize/8 , like:16 ,32

* @param {Buffer} key

* @return {}

*/

function checkKey(key) {

if (!key) {

throw 'AES.checkKey error: key is null ';

}

if (key.length !== (keySize / 8)) {

throw 'AES.checkKey error: key length is not ' + (keySize / 8) + ': ' + key.length;

}

}

/**

* buffer/bytes encription

* @param {Buffer} buff

* @param {Buffer} key the length must be 16 or 32

* @param {Buffer} [newIv] default is [0,0...0]

* @return {encripted Buffer}

*/

function encBytes(buff, key, newIv) {

checkKey(key);

var iv = newIv || IV;

if (cipherMode === ECB) iv = NULL_IV;

var cipher = crypto.createCipheriv(algorithm, key, iv);

cipher.setAutoPadding(true);

var re = Buffer.concat([cipher.update(buff), cipher.final()]);

// console.log('enc re:%s,len:%d', printBuf(re), re.length);

return re;

}

/**

* text encription

* @param {string} text

* @param {Buffer} key the length must be 16 or 32

* @param {Buffer} [newIv] default is [0,0...0]

* @param {string} [input_encoding] ["utf8" -default,"ascii","base64","binary"...](https://nodejs.org/api/buffer.html#buffer_buffer)

* @param {string} [output_encoding] ["base64" -default,"hex"]

* @return {string} encription result

*/

function encText(text, key, newIv, input_encoding, output_encoding) {

checkKey(key);

var iv = newIv || IV;

if (cipherMode === ECB) iv = NULL_IV;

var inEncoding = input_encoding || inputEncoding;

var outEncoding = output_encoding || outputEncoding;

var buff = new Buffer(text, inEncoding);

var out = encBytes(buff, key, iv);

var re = new Buffer(out).toString(outEncoding);

return re;

}

/**

* buffer/bytes decription

* @param {Buffer} buff

* @param {Buffer} key the length must be 16 or 32

* @param {Buffer} [newIv] default is [0,0...0]

* @return {encripted Buffer}

*/

function decBytes(buff, key, newIv) {

checkKey(key);

var iv = newIv || IV;

if (cipherMode === ECB) iv = NULL_IV;

var decipher = crypto.createDecipheriv(algorithm, key, iv);

decipher.setAutoPadding(true);

var out = Buffer.concat([decipher.update(buff), decipher.final()]);

return out;

}

/**

* text decription

* @param {string} text

* @param {Buffer} key the length must be 16 or 32

* @param {Buffer} [newIv] default is [0,0...0]

* @param {string} [input_encoding] ["utf8" - default,"ascii","base64","binary"...](https://nodejs.org/api/buffer.html#buffer_buffer)

* @param {string} [output_encoding] ["base64"- default ,"hex"]

* @return {string} decription result

*/

function decText(text, key, newIv, input_encoding, output_encoding) {

checkKey(key);

var iv = newIv || IV;

if (cipherMode === ECB) iv = NULL_IV;

var inEncoding = input_encoding || inputEncoding;

var outEncoding = output_encoding || outputEncoding;

var buff = new Buffer(text, outEncoding);

var re = new Buffer(decBytes(buff, key, iv)).toString(inEncoding);

return re;

}

exports.setCipherMode = setCipherMode;

exports.setKeySize = setKeySize;

exports.encText = encText;

exports.encBytes = encBytes;

exports.decText = decText;

exports.decBytes = decBytes;

// 以下为测试部分

// //key是16进制,需要转换为buffer,转换后buffer长度为16,即aes128,如果buffer长度是32则是aes256

// var key = new Buffer("c4b84456c1379bec99c4d1b7e9f13173", 'hex');

// var key256 = new Buffer("c4b84456c1379bec99c4d1b7e9f13173c4b84456c1379bec99c4d1b7e9f13173", 'hex');

// var str = "helloworld 你好";

// var buffer = new Buffer(str,"utf8");

//

// //aes-ecb-128 buffer

// var buffer_encrypt = encBytes(buffer,key);

// var crypto_buffer =decBytes(buffer_encrypt,key);

// var str = crypto_buffer.toString();

// console.log(str);

//

// //aes-ecb-128 string

// var text_encrypt = encText(str,key);

// var text_decrypt =decText(text_encrypt,key);

// console.log(text_decrypt);

//

// text_encrypt = encText(str,key,null,'utf8','base64');

// text_decrypt =decText(text_encrypt,key,null,'utf8','base64');

// console.log(text_decrypt);

//

// //aes-cbc-128 buffer

// setCipherMode(CBC);

// var iv = new Buffer("abcdefgh12345678","utf8");//字符串一定是16位

// buffer_encrypt = encBytes(buffer,key,iv);

// crypto_buffer =decBytes(buffer_encrypt,key,iv);

// str = crypto_buffer.toString();

// console.log(str);

//

// //aes-cbc-128 string

// text_encrypt = encText(str,key,iv);

// text_decrypt =decText(text_encrypt,key,iv);

// console.log(text_decrypt);

//

// text_encrypt = encText(str,key,iv,'utf8','base64');

// text_decrypt =decText(text_encrypt,key,iv,'utf8','base64');

// console.log(text_decrypt);

//

//

// //aes-ecb-256 buffer

// setKeySize(256);

// setCipherMode(ECB);

// buffer_encrypt = encBytes(buffer,key256);

// crypto_buffer =decBytes(buffer_encrypt,key256);

// str = crypto_buffer.toString();

// console.log("256=="+str);

参考资料

 类似资料: