J
S端加密过程:
key的处理:
通过创建指定的key,key必须是16位/24位/32位其中一种,但是常用的3DES加密的key为24位,下面使用的就是24位,key的长度可以随意指定,在转换key时,如果key不足24位则余数补0(因为最小位数必须是0以上),如果key多余24位,则会截取前24位数,多余部分则舍弃掉。
3DES加密的模式配定,有两种常见的加密方式:ECB和CBC模式
第一种:ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
第二种:CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:
(1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
(2)第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
(3)第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
(4)之后的数据以此类推,得到Cn
(5)按顺序连为C1C2C3......Cn即为加密结果。
解密是加密的逆过程,步骤如下:
(1)首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
(2)将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
(3)将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
(4)之后依此类推,得到Dn
(5)按顺序连为D1D2D3......Dn即为解密结果。
这里注意一点,解密的结果并不一定是我们原来的加密数据,可能还含有你补得位,一定要把补位去掉才是你的原来的数据。
以下是的JS端的Demo,通过3DES加密解密,Base64编码解码,需要引入JQuery框架和封装好的3DES加密解密算法,编码解码js文件:crypto-js.js,jsencrypt.js 这三个文件末尾处有链接下载。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../js/jquery-2.2.3.min.js" charset="UTF-8"></script>
<script type="text/javascript" src="../js/crypto-js.js" charset="UTF-8"></script>
<script type="text/javascript" src="../js/jsencrypt.js" charset="UTF-8"></script>
<title>3DES加密解密与Base64编码解码处理数据</title>
<style type="text/css">
body {
margin: 100px;
}
p, button {
font-size: 30px;
}
.btn2 {
margin-left: 100px;
}
</style>
<script type="text/javascript">
//秘钥key
var key = "12345677654321";
//key不足24位自动以0(最小位数是0)补齐,如果多余24位,则截取前24位,后面多余则舍弃掉
var base64 = CryptoJS.enc.Utf8.parse(key)
//加密使用的是3DES中的ECB,解密对应的使用ECB
function encrypt() {
var text = document.getElementById("content").innerText;
var encrypt = CryptoJS.TripleDES.encrypt(text, base64, {
//iv: CryptoJS.enc.Utf8.parse('01234567'),//iv偏移量
//mode: CryptoJS.mode.CBC, //CBC模式
mode: CryptoJS.mode.ECB, //ECB模式
padding: CryptoJS.pad.Pkcs7//padding处理
}
);
var encryptData = encrypt.toString();//加密完成后,转换成字符串
document.getElementById("encrypt").innerText=encryptData;
}
//解密
function decrypt() {
var text = document.getElementById("encrypt").innerText;
var decrypt = CryptoJS.TripleDES.decrypt(text, base64, {
//iv: CryptoJS.enc.Utf8.parse('01234567'),
//mode: CryptoJS.mode.CBC,
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
);
//解析数据后转为UTF-8
var parseData = decrypt.toString(CryptoJS.enc.Utf8);
document.getElementById("decrypt").innerText=parseData;
}
</script>
</head>
<body>
<h1>原文:</h1><p id="content">我是加密数据,点击下方加密按钮给我加密</p>
<h1>加密编码后:</h1><p id="encrypt"></p>
<h1>解码解密后:</h1><p id="decrypt"></p>
<button οnclick="encrypt()">加密</button><button class="btn2" οnclick="decrypt()">解密</button>
</body>
</html>
Java端加密解密处理:
key的处理同上述一样,不足补0,多余则舍弃。为有不同的是:Java使用字符串DESede默认则是3DES加密,且模式使用的是ECB模式,PKCS5Padding ,系统默认配置后的全路径:DESede/ECB/PKCS5Padding,如果要使用CBC模式需要配置IV偏移量,指定全配置:DESede/CBC/PKCS5Padding,如若与JS端互相调用,则需要两端加密解密,编码解码的key,模式全部相同才可以解析出来。以下是ThreeDESUtils是Java端的加密解密,编码解码处理,注意顺序:
加密流程:3DES先加密,Base64再编码
解密流程:Base64先解码,3DES再解密
这里使用Base64编码是在android的环境下的,需要在android真机或模拟器上才能运行,如果在测试模式下,则会报错,后端则使用后端的编码处理。
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* 3DES加密解密和BASE64编码解码混合使用
*/
public class ThreeDESUtils {
//key必须在16位/24位/32位,下面使用的是24位,不足24位则后面余数补0填充满24位
public static final String key="12345677654321";
//定义加密算法,有DES、DESede(即3DES)、Blowfish
private static final String Algorithm = "DESede";
//如果使用DESede,默认则使用"DESede/ECB/PKCS5Padding" ECB:电子密码本形式加密,
// BCB:密码块链接加密
// private static final String DES = "DESede/ECB/PKCS5Padding";
// private static final String DES = "DESede/CBC/PKCS5Padding";
// private static final String DES = "DESede/ECB/NoPadding";
/**
* 3DES加密方法
* @param src 源数据的字节数组
* @return
*/
public static byte[] encryptMode(byte[] src,String key) {
try {
SecretKey deskey = new SecretKeySpec(build3DesKey(key), Algorithm); //生成密钥
Cipher c1 = Cipher.getInstance(Algorithm); //实例化负责加密/解密的Cipher工具类
c1.init(Cipher.ENCRYPT_MODE, deskey); //初始化为加密模式
return c1.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (Exception e3) {
e3.printStackTrace();
}
return null;
}
//3DES解密
public static byte[] decrypt(byte[] data,String key){
try {
SecretKey deskey = new SecretKeySpec(build3DesKey(key), Algorithm); //生成密钥
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.DECRYPT_MODE,deskey);
return cipher.doFinal(data);
} catch (Exception ex) {
//解密失败,打日志
ex.printStackTrace();
}
return null;
}
/**
* 3DES加密Base64编码处理方法
* @param bytes 字符串转的数组
* @param key 用于3DES加密解密的密钥
* @return 经过3DES+Base64加密后的字符串
*/
public static String encode3DesBase64(byte[] bytes, String key){
byte [] base = encryptMode(bytes,key);
return Base64.encodeToString(base,0);
}
/**
* 将3DES+Base64加密后的byte数组进行解密
* @param bytes 先3DES+Base64加密后的 byte数组
* @param key 用于3DES加密解密的密钥
* @return 未加密前的字符串
*/
public static String decode3DesBase64(byte[] bytes, String key){
byte[] b = null;
String result = null;
try {
b = decrypt(Base64.decode(bytes,0),key);
result = new String(b, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
//构建3DES密钥
public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
byte[] key = new byte[24]; //声明一个24位的字节数组,默认里面都是0
byte[] temp = keyStr.getBytes("UTF-8"); //将字符串转成字节数组
/*
* 执行数组拷贝
* System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
*/
if(key.length > temp.length){
//如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
System.arraycopy(temp, 0, key, 0, temp.length);
}else{
//如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
}
}
上面的Demo都是相通的,通过HTML里面的加密后的数据,java端可以解析出来,反之亦然。
JS端加密文件下载地址:https://download.csdn.net/download/bob_xing_yang/10431821