1、Angular5
2、Typescript
3、DES-ECB电码本模式
4、复杂度-较高,破解难度-较高
话不多说,下图即为加密后的cookies。
核心思想:
1、DES加密一共4中模式,其中仅有ECB模式允许自定义长度。其他必须是8的倍数,所以我们推荐使用ECB。
2、前后端需要约定一个key,不可泄露。
3、一般用于cookies,url传参,其中url传参时要注意URLEncode和Decode。
Angular下Typescript代码:
引入相关js,直接安装:npm install crypto-js
建议写在工具类中。
import * as CryptoJS from 'crypto-js/crypto-js';
//与后端约定的key
const NB_NETWORK_CONFIG.DESKey = '8008208820';
//加密
export function encryptedDES(data) {
const keyHex = CryptoJS.enc.Utf8.parse(NB_NETWORK_CONFIG.DESKey);
//模式为ECB padding为Pkcs7
const encrypted = CryptoJS.DES.encrypt(data, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
//加密出来是一个16进制的字符串
return encrypted.ciphertext.toString();
}
//解密
export function decryptedDES(data) {
const keyHex = CryptoJS.enc.Utf8.parse(NB_NETWORK_CONFIG.DESKey);
const decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse(data)
}, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
//以utf-8的形式输出解密过后内容
return decrypted.toString(CryptoJS.enc.Utf8);
}
Java加解密:
建议写在工具类中
package pres.sargent.blog.util;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Locale;
//DES加解密工具类
public class DESCryptography {
//与前端项目约定的DES密钥
private final static String KEY = "8008208820";
public static void main(String[] args) {
//加密
System.err.println(encryptedDES("19"));
//解密
System.err.println(decryptedDES("随意的"));
}
//加密
public static String encryptedDES(String content) {
byte[] encrypted = DES_ECB_Encrypt(content.getBytes(), KEY.getBytes());
if (encrypted == null) {
return null;
}
return byteToHexString(encrypted);
}
//解密
public static String decryptedDES(String content) {
try {
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, generateKey(KEY));
byte[] buf = cipher.doFinal(hexStr2Bytes(content));
return new String(buf, "utf-8");
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
//下方为工具
public static byte[] DES_ECB_Encrypt(byte[] content, byte[] keyBytes) {
try {
DESKeySpec keySpec = new DESKeySpec(keyBytes);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
System.out.println("exception:" + e.toString());
}
return null;
}
private static SecretKey generateKey(String secretKey)
throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes());
keyFactory.generateSecret(keySpec);
return keyFactory.generateSecret(keySpec);
}
public static byte[] hexStr2Bytes(String src) {
src = src.trim().replace(" ", "").toUpperCase(Locale.US);
int m = 0, n = 0;
int iLen = src.length() / 2; //计算长度
byte[] ret = new byte[iLen]; //分配存储空间
for (int i = 0; i < iLen; i++) {
m = i * 2 + 1;
n = m + 1;
ret[i] = (byte) (Integer.decode("0x" + src.substring(i * 2, m) + src.substring(m, n)) & 0xFF);
}
return ret;
}
public static String byteToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer(bytes.length);
String sTemp;
for (int i = 0; i < bytes.length; i++) {
sTemp = Integer.toHexString(0xFF & bytes[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
private static byte toByte(char c) {
byte b = (byte) "0123456789ABCDEF".indexOf(c);
return b;
}
}
到此结束。
业务场景:
前端点击登陆,携带16位编码的DES加密字符串通过JSON进后端,后端解密DES,传入数据库做验证。返回是否正确的用户。