18 changed files with 391 additions and 40 deletions
@ -0,0 +1,122 @@ |
|||
package com.userinformation.backend.util; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
|
|||
public class BtoAAtoB { |
|||
|
|||
|
|||
|
|||
private static String base64hash = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
|||
|
|||
|
|||
public static boolean isMatcher(String inStr ,String reg){ |
|||
Pattern pattern = Pattern.compile(reg); |
|||
Matcher matcher = pattern.matcher(inStr); |
|||
if(matcher.matches()){ |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
/** |
|||
* btoa method |
|||
* @param inStr |
|||
* @return |
|||
*/ |
|||
public static String btoa(String inStr){ |
|||
// if (/([^\u0000-\u00ff])/.test(s)) {
|
|||
// throw new Error('INVALID_CHARACTER_ERR');
|
|||
// }
|
|||
if(inStr == null || isMatcher(inStr ,"([^\\u0000-\\u00ff])")){ |
|||
return null; |
|||
} |
|||
StringBuilder result = new StringBuilder(); |
|||
int i=0; |
|||
int mod=0; |
|||
int ascii; |
|||
int prev=0; |
|||
while (i < inStr.length()){ |
|||
ascii = inStr.charAt(i); |
|||
mod = i % 3; |
|||
|
|||
|
|||
switch(mod){ |
|||
case 0: |
|||
result.append(String.valueOf(base64hash.charAt(ascii >> 2))); |
|||
break; |
|||
case 1: |
|||
result.append(String.valueOf(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)))); |
|||
break; |
|||
case 2: |
|||
result.append(String.valueOf(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)))); |
|||
result.append(String.valueOf(base64hash.charAt(ascii & 0x3f))); |
|||
break; |
|||
} |
|||
|
|||
|
|||
prev = ascii; |
|||
i++; |
|||
} |
|||
|
|||
|
|||
if(mod == 0) { |
|||
result.append(String.valueOf(base64hash.charAt((prev & 3) << 4))); |
|||
result.append("=="); |
|||
} else if (mod == 1) { |
|||
result.append(String.valueOf(base64hash.charAt((prev & 0x0f) << 2))); |
|||
result.append("="); |
|||
} |
|||
|
|||
|
|||
return result.toString(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* // atob method
|
|||
// 逆转encode的思路即可
|
|||
* @param inStr |
|||
* @return |
|||
*/ |
|||
public static String atob(String inStr){ |
|||
if(inStr == null) return null; |
|||
//s = s.replace(/\s|=/g, '');
|
|||
inStr = inStr.replaceAll("\\s|=", ""); |
|||
StringBuilder result = new StringBuilder(); |
|||
int cur; |
|||
int prev=-1; |
|||
// Integer prev=null;
|
|||
int mod; |
|||
int i=0; |
|||
while (i < inStr.length()){ |
|||
cur = base64hash.indexOf(inStr.charAt(i)); |
|||
mod = i % 4; |
|||
switch (mod){ |
|||
case 0: |
|||
break; |
|||
case 1: |
|||
result.append(String.valueOf( (char)( prev << 2 | cur >> 4 ) )); |
|||
break; |
|||
case 2: |
|||
result.append(String.valueOf((char)( (prev & 0x0f) << 4 | cur >> 2) )); |
|||
break; |
|||
case 3: |
|||
result.append(String.valueOf( (char)((prev & 3) << 6 | cur) )); |
|||
break; |
|||
} |
|||
prev = cur; |
|||
i++; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
return result.toString(); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,121 @@ |
|||
package com.userinformation.backend.util; |
|||
|
|||
import javax.crypto.Cipher; |
|||
import javax.crypto.spec.SecretKeySpec; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.security.SecureRandom; |
|||
import java.util.Random; |
|||
|
|||
import org.apache.commons.codec.binary.Base64; |
|||
|
|||
/** |
|||
* @describe: Aes加密 |
|||
* @author: xiaowuler |
|||
* @createTime: 2021-12-07 16:59 |
|||
*/ |
|||
public class Coder { |
|||
|
|||
public static final String DEFAULT_KEY = "XiaowuleVeryCool"; |
|||
|
|||
/** |
|||
* 加密算法AES |
|||
*/ |
|||
private static final String KEY_ALGORITHM = "AES"; |
|||
|
|||
/** |
|||
* key的长度,Wrong key size: must be equal to 128, 192 or 256 |
|||
* 传入时需要16、24、36 |
|||
*/ |
|||
private static final Integer KEY_LENGTH = 16 * 8; |
|||
|
|||
/** |
|||
* 算法名称/加密模式/数据填充方式 |
|||
* 默认:AES/ECB/PKCS5Padding |
|||
*/ |
|||
private static final String ALGORITHMS = "AES/ECB/PKCS5Padding"; |
|||
|
|||
/** |
|||
* 后端AES的key,由静态代码块赋值 |
|||
*/ |
|||
public static String key; |
|||
|
|||
static { |
|||
key = getKey(); |
|||
} |
|||
|
|||
/** |
|||
* 获取key |
|||
*/ |
|||
public static String getKey() { |
|||
StringBuilder uid = new StringBuilder(); |
|||
//产生16位的强随机数
|
|||
Random rd = new SecureRandom(); |
|||
for (int i = 0; i < KEY_LENGTH / 8; i++) { |
|||
//产生0-2的3位随机数
|
|||
int type = rd.nextInt(3); |
|||
switch (type) { |
|||
case 0: |
|||
//0-9的随机数
|
|||
uid.append(rd.nextInt(10)); |
|||
break; |
|||
case 1: |
|||
//ASCII在65-90之间为大写,获取大写随机
|
|||
uid.append((char) (rd.nextInt(25) + 65)); |
|||
break; |
|||
case 2: |
|||
//ASCII在97-122之间为小写,获取小写随机
|
|||
uid.append((char) (rd.nextInt(25) + 97)); |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
return uid.toString(); |
|||
} |
|||
|
|||
/** |
|||
* 加密 |
|||
* |
|||
* @param content 加密的字符串 |
|||
* @param encryptKey key值 |
|||
*/ |
|||
public static String encrypt(String content, String encryptKey) throws Exception { |
|||
//设置Cipher对象
|
|||
Cipher cipher = Cipher.getInstance(ALGORITHMS, getInstance()); |
|||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), KEY_ALGORITHM)); |
|||
|
|||
//调用doFinal
|
|||
byte[] b = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)); |
|||
|
|||
// 转base64
|
|||
return Base64.encodeBase64String(b); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 解密 |
|||
* |
|||
* @param encryptStr 解密的字符串 |
|||
* @param decryptKey 解密的key值 |
|||
*/ |
|||
public static String decrypt(String encryptStr, String decryptKey) throws Exception { |
|||
//base64格式的key字符串转byte
|
|||
byte[] decodeBase64 = Base64.decodeBase64(encryptStr); |
|||
//设置Cipher对象
|
|||
Cipher cipher = Cipher.getInstance(ALGORITHMS, getInstance()); |
|||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), KEY_ALGORITHM)); |
|||
|
|||
//调用doFinal解密
|
|||
byte[] decryptBytes = cipher.doFinal(decodeBase64); |
|||
return new String(decryptBytes); |
|||
} |
|||
|
|||
private static org.bouncycastle.jce.provider.BouncyCastleProvider bouncyCastleProvider = null; |
|||
|
|||
public static synchronized org.bouncycastle.jce.provider.BouncyCastleProvider getInstance() { |
|||
if (bouncyCastleProvider == null) { |
|||
bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider(); |
|||
} |
|||
return bouncyCastleProvider; |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
module.exports = { |
|||
plugins: { |
|||
'autoprefixer': {browsers: 'last 5 version'} |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
{ |
|||
"presets": [ |
|||
["es2015", { "modules": false }] |
|||
], |
|||
"plugins": ["transform-object-rest-spread"] //不能解析es6语法关键解决 |
|||
} |
@ -0,0 +1,25 @@ |
|||
var CryptoJS: any; |
|||
import("crypto-js").then((response) => { |
|||
CryptoJS = response; |
|||
}); |
|||
const defaultKey = "XiaowuleVeryCool"; |
|||
|
|||
export function encrypt(plaintext, key: string = defaultKey) { |
|||
if (plaintext instanceof Object) { |
|||
//JSON.stringify
|
|||
plaintext = JSON.stringify(plaintext) |
|||
} |
|||
let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(plaintext), CryptoJS.enc.Utf8.parse(key), {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); |
|||
return encrypted.toString(); |
|||
} |
|||
|
|||
//解密
|
|||
export function decrypt(ciphertext, key: string = defaultKey) { |
|||
let decrypt = CryptoJS.AES.decrypt(ciphertext, CryptoJS.enc.Utf8.parse(key), {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); |
|||
let decString = CryptoJS.enc.Utf8.stringify(decrypt).toString(); |
|||
if(decString.charAt(0) === "{" || decString.charAt(0) === "[" ){ |
|||
//JSON.parse
|
|||
decString = JSON.parse(decString); |
|||
} |
|||
return decString; |
|||
} |
Loading…
Reference in new issue