文章目录
- 前端加密测试
- Java加解密代码
写了个新的前端项目,公司要求,账号密码这些必须是加密传输的;后端使用了GCM
模式加密,前端是复制的一个以前项目的代码,原来是有写加密的,使用的是CryptoJS
组件CTR
模式加密的,但是这个组件里面没有GCM
加密模式,找了半天,发现浏览器其实是自带加密的组件的window.crypto
,使用这个组件就可以使用GCM
模式加密,代码贴在下面,顺便java
代码也贴出来了。
CryptoJS
看点进源码里面看了下只支持这几种模式
去官网看了下 https://cryptojs.gitbook.io/docs#hashing,也是说支持这几种,估计是浏览器都支持了,所以CryptoJS
也就没有再更新了吧
前端加密测试
包含了完整的加密解密代码,可以拷过去直接用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>加密小工具</title>
</head>
<body>
<textarea rows="8" cols="40" id="content"></textarea>
<br>
<button onclick="encrypt1()">加密</button>
<button onclick="decrypt1()">解密</button>
<p>结果: <label id='result'></label></p>
</body>
<script type="text/javascript">
// 将字符串转换为字节数组
function stringToUint8Array(str) {
let arr = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
arr[i] = str.charCodeAt(i);
}
return arr;
}
// 导入密钥
async function importKey(keyStr) {
const keyBytes = stringToUint8Array(keyStr);
const key = await window.crypto.subtle.importKey(
'raw',
keyBytes,
'AES-GCM', // 或者其他算法
false,
['encrypt', 'decrypt']
);
return key;
}
// 加密函数
async function encrypt(message, key, iv) {
let msgBuffer = new TextEncoder().encode(message);
let ivBytes = stringToUint8Array(iv);
let ciphertext = await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: ivBytes
},
key,
msgBuffer
);
return ciphertext;
}
async function decrypt(base64Ciphertext, key, iv) {
// 将 Base64 字符串转换回 ArrayBuffer
let ciphertext = window.atob(base64Ciphertext);
let ciphertextBuffer = new Uint8Array(ciphertext.length);
for (let i = 0; i < ciphertext.length; i++) {
ciphertextBuffer[i] = ciphertext.charCodeAt(i);
}
let ivBytes = stringToUint8Array(iv);
let plaintext = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: ivBytes
},
key,
ciphertextBuffer.buffer
);
// 将 ArrayBuffer 转换为字符串
let decoder = new TextDecoder();
return decoder.decode(plaintext);
}
let key;
let ivStr;
(async () => {
const keyStr = "你的密钥"; //"29H3LCRC49SGFR0A";
ivStr = "iv信息"; //"FBTR064AT3LCRF4E";
key = await importKey(keyStr);
const ciphertext = await encrypt("uIv86omN9Fp#", key, ivStr);
console.log("Encrypted:", ciphertext);
})();
function encrypt1() {
const txt = document.getElementById("content").value;
encrypt(txt, key, ivStr).then((ciphertext) => {
console.log("Encrypted:", btoa(String.fromCharCode(...new Uint8Array(ciphertext))));
document.getElementById("result").innerText = btoa(String.fromCharCode(...new Uint8Array(ciphertext)));
});
}
function decrypt1() {
const txt = document.getElementById("content").value;
decrypt(txt, key, ivStr).then((plaintext) => {
console.log("Decrypted:", plaintext);
document.getElementById("result").innerText = plaintext;
});
}
</script>
</html>
Java加解密代码
要先引入一个包
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.77</version>
</dependency>
package com.yuanjy.sf04;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLDecoder;
import java.security.Security;
import java.util.Base64;
public class GCMTest {
private static String key = "你的密钥"; //"29H3LCRC49SGFR0A";
private static String ivParameter = "iv信息"; //"FBTR064AT3LCRF4E";
private static IvParameterSpec IV;
private static final String ALGORITHMSTR = "AES/GCM/NoPadding";
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
System.out.println(encrypt("admin", key));
System.out.println(decrypt("yagZI4sMNgee5R/AXhdFCPAjF1k4"));
}
public static String decrypt(String encrypt) throws Exception {
return URLDecoder.decode(decrypt(encrypt, key), "UTF-8");
}
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
return decryptByBytes(Base64.getDecoder().decode(encryptStr), decryptKey);
}
public static String decryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
byte[] iv = ivParameter.getBytes();
IV = new IvParameterSpec(iv);
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(ALGORITHMSTR, "BC");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"), IV);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
public static String encrypt(String content, String encryptKey) throws Exception {
return Base64.getEncoder().encodeToString(encryptToBytes(content, encryptKey));
}
public static byte[] encryptToBytes(String content, String encryptKey) throws Exception {
byte[] iv = ivParameter.getBytes();
IV = new IvParameterSpec(iv);
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR, "BC");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"), IV);
return cipher.doFinal(content.getBytes("utf-8"));
}
}