實際開發(fā)中客戶端與服務(wù)端的通信內(nèi)容往往需要通過密文傳輸枪狂,本文將介紹可以實現(xiàn)Java與js的互相加解密的AES加密方式
Java語言實現(xiàn)
public class AESTest {
//static String data = "123456RWEQR";
static String key = "abcdef0123456789"; //16位
static String iv = "0123456789abcdef"; //16位
public static void main(String args[]) throws Exception {
System.out.println(encryptAES("123456"));
System.out.println(decryptAES(encryptAES("123456")));
}
public static String encryptAES(String data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding"); //參數(shù)分別代表 算法名稱/加密模式/數(shù)據(jù)填充方式
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes();
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return new sun.misc.BASE64Encoder().encode(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decryptAES(String data) throws Exception {
try {
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(data);
Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
js實現(xiàn)
需要引入 aes.js依賴包 密碼:oeer
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AES TEST</title>
</head>
<body>
<p>待加密值:123456RWEQR</p>
<p id="p1"></p>
<p id="p2"></p>
<script type="text/javascript" src="js/vendor/jquery-1.12.0.min.js"></script>
<script type="text/javascript" src="js/aes/aes.js"></script>
<script type="text/javascript" src="js/aes/pad-zeropadding.js"></script>
<script type="text/javascript">
$(function () {
var data = "123456RWEQR";
var key = CryptoJS.enc.Latin1.parse('abcdef0123456789');
var iv = CryptoJS.enc.Latin1.parse('0123456789abcdef');
//加密
var encrypted = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
$("#p1").text("加密結(jié)果:"+encrypted.toString());
console.log(encrypted.toString())
//解密
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv, padding: CryptoJS.pad.ZeroPadding});
console.log(decrypted.toString(CryptoJS.enc.Utf8));
$("#p2").text("解密結(jié)果:"+decrypted.toString(CryptoJS.enc.Utf8));
})
</script>
</body>
</html>
AES四種常用的加密模式
對稱/分組密碼一般分為流加密(如OFB咏删、CFB等)和塊加密(如ECB淌实、CBC等)。對于流加密概行,需要將分組密碼轉(zhuǎn)化為流模式工作细层。對于塊加密(或稱分組加密),如果要加密超過塊大小的數(shù)據(jù)倦逐,就需要涉及填充和鏈加密模式譬正。
一、 ECB(Electronic Code Book電子密碼本)模式
ECB模式是最早采用和最簡單的模式檬姥,它將加密的數(shù)據(jù)分成若干組曾我,每組的大小跟加密密鑰長度相同,然后每組都用相同的密鑰進(jìn)行加密健民。
優(yōu)點:
1.簡單抒巢; 2.有利于并行計算; 3.誤差不會被傳送秉犹;
缺點: 1.不能隱藏明文的模式蛉谜; 2.可能對明文進(jìn)行主動攻擊; 因此崇堵,此模式適于加密小消息型诚。
二、CBC(Cipher Block Chaining鸳劳,加密塊鏈)模式
優(yōu)點:
1.不容易主動攻擊,安全性好于ECB,適合傳輸長度長的報文,是SSL狰贯、IPSec的標(biāo)準(zhǔn)」髟
缺點: 1.不利于并行計算暮现; 2.誤差傳遞; 3.需要初始化向量IV且必須是16字節(jié)
三楚昭、CFB(Cipher FeedBack Mode栖袋,加密反饋)模式
優(yōu)點:
1.隱藏了明文模式; 2.分組密碼轉(zhuǎn)化為流模式; 3.可以及時加密傳送小于分組的數(shù)據(jù);
缺點: 1.不利于并行計算; 2.誤差傳送:一個明文單元損壞影響多個單元; 3.唯一的IV;
四、OFB(Output FeedBack抚太,輸出反饋)模式
優(yōu)點:
1.隱藏了明文模式; 2.分組密碼轉(zhuǎn)化為流模式; 3.可以及時加密傳送小于分組的數(shù)據(jù);
缺點: 1.不利于并行計算; 2.對明文的主動攻擊是可能的; 3.誤差傳送:一個明文單元損壞影響多個單元
AES三中數(shù)據(jù)填充方式
PKCS7Padding
Java不支持此方式
PKCS7Padding是缺幾個字節(jié)就補幾個字節(jié)的0
PKCS5Padding
JS不支持此方式
PKCS5Padding是缺幾個字節(jié)就補充幾個字節(jié)的幾塘幅,例如缺8個字節(jié)昔案,就補充8個字節(jié)的8
NOPadding
不補充字節(jié)