如何在项目中保证用户数据安全-前后端亲测有效
源码地址
步骤:
比如用户修改密码:
- server端 生成base64编码后的公私钥
- server端 send base64编码后的私钥
- web端保存私钥
- server端随机生成16位字符串->私钥加密字符串->加密字符串->base64编码加密字符串(base64编码) response web
- web端解码base64编码加密字符串->加密字符串->用私钥解密加密字符串->原生字符串
- web端拼接字符串加密码->AES原生字符串加密前者(字符串加密码) send server
- server端对用AES加密字符串(包含密码)AES解密->校验原生字符串是否正确–>获取原生密码->加密入库
部分demo:
RSA非对称加密工具类:
package cloud.xulehuang.example.password_security.非对称加密;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
/**
* <p>
* rsa 加密工具
*/
public class RsaUtil {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return encode(signature.sign());
}
/**
* <p>
* 校验数字签名
* </p>
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
*
* @return
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
byte[] keyBytes = decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(decode(sign));
}
/**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
throws Exception {
byte[] keyBytes = decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
throws Exception {
byte[] keyBytes = decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* <p>
* 公钥加密
* </p>
*
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey)
throws Exception {
byte[] keyBytes = decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 私钥加密
* </p>
*
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
throws Exception {
byte[] keyBytes =decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return encode(key.getEncoded());
}
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
System.out.println("base64编码前" + key.getEncoded());
return encode(key.getEncoded());
}
/**
* base64 加密
* @param bytes
* @return
* @throws Exception
*/
public static String encode(byte[] bytes) throws Exception {
return new String(Base64.encodeBase64(bytes));
}
/**
* base64 解密
* @param base64
* @return
* @throws Exception
*/
public static byte[] decode(String base64) throws Exception {
return Base64.decodeBase64(base64.getBytes());
}
/**
* @Description: 解密
* @Param: [data, privateKey]
* @return: java.lang.String
* @Author: anxingtao
* @Date: 2019-3-13 11:06
*/
public static String decrypt(String data, String privateKey) throws Exception {
byte[] pubdata = decryptByPrivateKey(decode(data), privateKey);
return new String(pubdata, "UTF-8");
}
/**
* @Description: 加密
* @Param: [data, publicKey]
* @return: java.lang.String
* @Author: anxingtao
* @Date: 2019-3-13 11:10
*/
public static String encrypt(String data, String publicKey) throws Exception {
byte[] pubdata = encryptByPublicKey(data.getBytes("UTF-8"), publicKey);
String outString = new String(encode(pubdata));
return outString;
}
/**
* @title encrypriva
* @description 私钥加密
* @author Administrator
* @updateTime 2021/8/11 16:31
*/
public static String encrypk(String data, String privateKey) throws Exception {
byte[] resdata = encryptByPrivateKey(data.getBytes("UTF-8"), privateKey);
String outString = new String(encode(resdata));
return outString;
}
/**
* @title decrypk
* @description 公钥解密
* @author Administrator
* @updateTime 2021/8/11 16:32
*/
/* public static String decrypk(String data, String publicKey) throws Exception {
byte[] resdata = decryptByPublicKey(decode(data), publicKey);
return new String(resdata, "UTF-8");
}*/
public static void main(String[] args) throws Exception {
/* String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALbGpPkikVf51rzHHr5rCmtIjpsq9Pked0W5xu5Khf4fQEl7utYahfC3dleFaCyLkD39Q1PpyOrQm7YQPSxkHR7Bn/w/CA93EYNKXG1cAZjDr/ZJAd6xUY2K4GkriWB9v4OeCTThkKwfharJJW270No5VT49ktKAHKkug/WnCUN7AgMBAAECgYEAlxPNK20qTFjj6biBLg5WV2VrEtFIGl7XYdf0meUZqnr0bYkLX4we6GENPby05hUaTlL4gvT8MTPrcWss1XOPKQYRrSjLBZmmCiYe+SDxx0ZPmNN1db86X0ahQsNzxAVkTyIKKVW1SxwyvIOSN5H71yyBzZj/yG0qymj8H0hBVFkCQQDijlLZ9E7pGT/2HLitxEyi02kIjlsgLtjmk8NP8if5eCspmKXaw3xH2j3BLOGDGZUjeQGZcyOOHdGnNkbUVSdtAkEAzoe6ugzr63r70CwbWAEBQLRUfX4i8fiLazlCybhVAMEKjbKTdcAUFLfKNmharPHE/dlHLja/dReaLMKB7l69hwJABcM/AkI/m5hD0zvJysm6dU3RVyFf2gK3C65ogmkTcToIRweV+GmOiLlZZseAePg2ne9fBgsytVO22Hz98jq0RQJAGOyOX0eR7RAhdYTtI9izMwDQNXjUdMke4ii946QoNfgV8vW7D/nHMpzffWNolfhzYoMnMO+QeWwIwiATGBY83wJBAN5aLGltsuW/6ILvMTgciwdQlO3dTjzFXhbXURsyKWYF6QJnaeqNMVqr9F0lWXKQyuIu+mj5JRkZszOvS0jczNA=\n";
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2xqT5IpFX+da8xx6+awprSI6bKvT5HndFucbuSoX+H0BJe7rWGoXwt3ZXhWgsi5A9/UNT6cjq0Ju2ED0sZB0ewZ/8PwgPdxGDSlxtXAGYw6/2SQHesVGNiuBpK4lgfb+Dngk04ZCsH4WqySVtu9DaOVU+PZLSgBypLoP1pwlDewIDAQAB";
String msg = "{\"dev_id\":\"868989034328943\",\"user_id\":\"\",\"team_id\":\"\"}";
//String msg = DateTimeUtil.getDate();
String sm = RsaUtil.encrypt(msg,publicKey);
System.out.println(sm);*/
String str = "IGCJsmAEdYDle/WYAS4qd3hCp9TAZRz806Sm8p4KepJ2XuDaOnKh65homSgZJ88/pQs5rEm6Qmsg+8JqMgqjixD8jZhnToVriKzkhHe2UarS+sT8oUAvXrO98FwZv7GELgt4mCuitwxrREYq4QUtwI6Fc+SGdF0BjeKNUSWHifg=";
//
//
//
// String s = RSAUtils.decrypt(sm,privateKey);
// System.out.println(s);
//生成密钥对(公钥和私钥)
Map map = RsaUtil.genKeyPair();
System.out.println("----------------公钥----------------");
System.out.println(RsaUtil.getPublicKey(map));
System.out.println("----------------私钥----------------");
System.out.println(RsaUtil.getPrivateKey(map));
// String str = RSAUtils.encrypk("我爱你中国",privateKey);
// System.out.println(str);
//
// String res = RSAUtils.decrypk(str,publicKey);
// System.out.println(res);
// String content = "F2cgqkTN1DehdikNnKtt5t0p+HrOr4hwWrbf9MGmksWUQFwWzFPbwt1at7uXYp8mt88KiIHrD/yKe8pkdzuq2VMTyvObryIbVannBHtzrhjBd2FoRQpaorMWtFuv7MZY3WmuqhzdhXMXAx1pB/hmEToncvW3ZpEWp7N5ItO89H8=";
// String priKey = "MIICYQIBAAKBgQCijkoTGTel/S62WwUpXswc8m7Fdp+SY2ZMZKV8FeRD5QUi1mGYUHqmab7w/xN2vdNWI9sR9MPL4aO2IA57HD4HTGmidyCDmxl8QCRMSNwXroIP6mWpI5lHjajPth25n2gwsnYoAvrSfTnTkUAmoKUtQSg3/AZ9Rg8mf8NFY5AjGwIDAQABAoGBAJqS8W9NyHPn2DaBQNxBD5jrE1hj34NFT+6OuinPa1sAeSzSbMV4qdh6r53dADYmdcLwn41okZLbAmDaBBscUUZo/pIUPdGgU+P7RqpMtfwbq/RoleFpU2GWBErJ7/qKe6cfcEyuBhAMG8vLqtfA70P75vFAMoKhzWsUGtD5gQVZAkUAuRjD839QS/u17Xv6jWbcw0vxTD2UN/hyObyQORlX+LjxC5RCuYwkkWoXIGe94hzsyCoURc6RhakRM/LyqhCliTQ+PvcCPQDg0xUHm2qr8jfo1PTYf6Ks8Id9FZiqxD1VJh2OoRMSTCPo8O4PskbzictNu2siFLt0r3EKjCDP1jP0H/0CRFSsO5d8OiNINmU5PdjJoVvFtdCGqvMfuEEpPWChc1jYYYxGem+e6GuM+J9eVcLGMJswhK2aXX+jY7c8AD5D9zXYrFDpAj0Ap5OOXEIyy4FavRhmfCz+wyrxwoFjbv2gvaQQaeyTu5K3PXy/5UE783Ek8Yad/yQ26W2Ps43pMyF1TiS9AkQrfddTmrz7OZEfFtgaHuSj/8gbkGEdr7H8YIML/wZ1ozDkfxwsnzgclJXir/Qb2VjGOSzfUrlj2SaxgqIGfKI7DyEWeg==";
// System.out.println(priKey);
//
// String priKey2 = "MIICewIBADANBgkqhkiG9w0BAQEFAASCAmUwggJhAgEAAoGBAKKOShMZN6X9LrZbBSlezBzybsV2n5JjZkxkpXwV5EPlBSLWYZhQeqZpvvD/E3a901Yj2xH0w8vho7YgDnscPgdMaaJ3IIObGXxAJExI3Beugg/qZakjmUeNqM+2HbmfaDCydigC+tJ9OdORQCagpS1BKDf8Bn1GDyZ/w0VjkCMbAgMBAAECgYEAmpLxb03Ic+fYNoFA3EEPmOsTWGPfg0VP7o66Kc9rWwB5LNJsxXip2Hqvnd0ANiZ1wvCfjWiRktsCYNoEGxxRRmj+khQ90aBT4/tGqky1/Bur9GiV4WlTYZYESsnv+op7px9wTK4GEAwby8uq18DvQ/vm8UAygqHNaxQa0PmBBVkCRQC5GMPzf1BL+7Xte/qNZtzDS/FMPZQ3+HI5vJA5GVf4uPELlEK5jCSRahcgZ73iHOzIKhRFzpGFqREz8vKqEKWJND4+9wI9AODTFQebaqvyN+jU9Nh/oqzwh30VmKrEPVUmHY6hExJMI+jw7g+yRvOJy027ayIUu3SvcQqMIM/WM/Qf/QJEVKw7l3w6I0g2ZTk92MmhW8W10Iaq8x+4QSk9YKFzWNhhjEZ6b57oa4z4n15VwsYwmzCErZpdf6NjtzwAPkP3NdisUOkCPQCnk45cQjLLgVq9GGZ8LP7DKvHCgWNu/aC9pBBp7JO7krc9fL/lQTvzcSTxhp3/JDbpbY+zjekzIXVOJL0CRCt911OavPs5kR8W2Boe5KP/yBuQYR2vsfxggwv/BnWjMOR/HCyfOByUleKv9BvZWMY5LN9SuWPZJrGCogZ8ojsPIRZ6";
//
// System.out.println(RSAUtils.decrypt(content,priKey2));
}
}
AES对称加密工具类:
package cloud.xulehuang.example.password_security.对称加密;
import org.apache.commons.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtil {
private static String iv = "0123456789ABCDEF";//偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
private static String Algorithm = "AES";
private static String AlgorithmProvider = "AES/ECB/PKCS5Padding"; // 算法/模式/补码方式
//暂时不用这里的,使用随机生成的字符串
public static byte[] generatorKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);
keyGenerator.init(256);//默认128,获得无政策权限后可为192或256
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
}
public static IvParameterSpec getIv() throws UnsupportedEncodingException {
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
System.out.println("偏移量:"+byteToHexString(ivParameterSpec.getIV()));
return ivParameterSpec;
}
/**
* 加密
* */
public static byte[] AES_CBC_Encrypt(byte[]content, byte[] keyBytes){
try{
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv.getBytes()));
byte[]result=cipher.doFinal(content);
return result;
}catch (Exception e) {
System.out.println("exception:"+e.toString());
}
return null;
}
/**
* 解密
* */
public static byte[] AES_CBC_Decrypt(byte[]content, byte[] keyBytes){
try{
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv.getBytes()));
byte[]result=cipher.doFinal(content);
return result;
}catch (Exception e) {
// TODO Auto-generated catchblock
System.out.println("exception:"+e.toString());
}
return null;
}
/**
* 将byte转换为16进制字符串
* @param src
* @return
*/
public static String byteToHexString(byte[] src) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xff;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
sb.append("0");
}
sb.append(hv);
}
return sb.toString();
}
/**
* 将16进制字符串装换为byte数组
* @param hexString
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] b = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return b;
}
/**
* 字符串装换成base64
*
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception {
return Base64.decodeBase64(key.getBytes());
}
/**
*二进制装换成base64
*
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[]key) throws Exception {
return new String(Base64.encodeBase64(key));
}
/**将16进制字符串转换为二进制字节数组
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i< hexStr.length()/2; i++) {
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**将二进制字节数组转换为16进制字符串
* @param
* @return
*/
public static String parseByte2HexStr(byte buf[]){
StringBuffer sb = new StringBuffer();
for(int i = 0; i < buf.length; i++){
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
测试类:
package cloud.xulehuang.example.password_security;
import cloud.xulehuang.example.password_security.对称加密.AESUtil;
import cloud.xulehuang.example.password_security.非对称加密.RsaUtil;
import org.apache.commons.codec.binary.Base64;
import java.util.Map;
import java.util.UUID;
public class ExampleText {
public static void main(String[] args) throws Exception {
Map rsaMap = RsaUtil.genKeyPair();
//获取公钥、私钥,私钥不断变化,应该将私钥实时更新到前端,或者把两者保存起来
String rsaPublicKey = (String)RsaUtil.getPublicKey(rsaMap);
System.out.println("base64编码的公钥:" + rsaPublicKey);
String rsaPrivateKey = (String)RsaUtil.getPrivateKey(rsaMap);
System.out.println("base64编码的私钥:" + rsaPrivateKey);
//随机生成16位字符串
String randomString = UUID.randomUUID().toString().substring(0, 16);
System.out.println("随机生成的字符串:" + randomString);
//公钥加密字符串
String randomStringEncodeByDecodeRsaPublicKey = RsaUtil.encrypt(randomString, rsaPublicKey);
System.out.println("公钥加密的随机生成的字符串:" + randomStringEncodeByDecodeRsaPublicKey);
//编码加密字符串,送到客户端
String randomStringEncodeByDecodeRsaPublicKeyWithBase64 = new String(Base64.encodeBase64(randomStringEncodeByDecodeRsaPublicKey.getBytes()), "UTF-8");
System.out.println("base64编码的公钥加密的随机生成的字符串:" + randomStringEncodeByDecodeRsaPublicKeyWithBase64);
//客户端解码,得到加密字符串
String randomStringDecodeByDecodeRsaPublicKeyWithBase64 = new String(Base64.decodeBase64(randomStringEncodeByDecodeRsaPublicKeyWithBase64) , "UTF-8");
System.out.println("base64解码的公钥加密的随机生成的字符串:" + randomStringDecodeByDecodeRsaPublicKeyWithBase64);
//私钥解密加密字符串
String originRandomString = RsaUtil.decrypt(randomStringDecodeByDecodeRsaPublicKeyWithBase64, rsaPrivateKey);
System.out.println("私钥解密加密的字符串:" + originRandomString);;
//AES解密字符串
byte[] originRandomStringAndPassword = AESUtil.AES_CBC_Decrypt(Base64.decodeBase64("KlQGSJEJtnRaWyCRVVD+3fOo82Sp/vSqffae7+xNERQ=") ,"25a725ea-4782-44".getBytes());
System.out.println("AES解密的包含随机字符串和密码的加密字符串" + new String(originRandomStringAndPassword , "UTF-8"));
}
}
前端:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script th:src="@{/password_security/crypto-js-develop/src/rsa.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/crypto-js.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/core.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/evpkdf.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/cipher-core.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/enc-base64.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/enc-base64url.js}"></script>
<script th:src="@{/password_security/crypto-js-develop/src/enc-utf16.js}"></script>
<!--<script src="https://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script>-->
</head>
<body>
</body>
<script>
var encrypt = new JSEncrypt();
//获取私钥
var private = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMWsnge1ll+ze0CuWLcRw58OY2GAUKAXC1GA15EvroIY4O+T6C3DL7ZtWs2NbOhFn4Ps6upDANvIjhMQfhKb9qdVGBS4elXTPAaV8mM5FHeUAsum6YCuwSSVA9boyvqeN8oeTCrhw4iLcabfoWpeZzV4wXlkWkhSMn6aTs7MPrevAgMBAAECgYBuOx486lQatfmrTg4GuI8/6UQeIPHU9ETJhHGxcsd7oOf+cZptuoSm1EBok88Bj6GubbVqQUb/SM2BcBb9xZ87H+MkGXtDZIlCgosWsLvjkVFMUzjg8hlhI2bnhmWGyMguK0CRAHXGzXpYN1VaD/b2ig2PphsRmi21vTgGzv8VwQJBAP8xXiCheAu3wdm/1VOLgac4n9DmSVA2QLqziOTR3WU/I8o6h2Stq27W3UtTRZRb7Gx6weI+DIDTWlOpa2Mm9pECQQDGTK0eQtRzRYL0K1ENtfxf//FwktfNULaDBMkm64fK4ECJn3xIPDaqzzpfvmTcTjv/bbjXbLGTM4QVAtxykGo/AkEA55aSuIQwoFmz53uLClV5ZRsjFf5XHB8QIR8bJaU7CU4Cmd0B0CE3idAeZeR9KYU+irfgygPLbwHfYDtJBGNwsQJBAKlmg1WgncFDlpVkE7/0wX55NRaIO1aoJuJSSky3VK/ZVwi6d/91gPX2RdXY3mzdYJ/aadeOgTxQ+/q/EPfFqx0CQHK3+ql2gEy/sCaXxkK6TnpP7MATmEYQl1sO4xbjhZ2lQ8mul1vTBEQVIohgMy2uoOoxuywGMZZBoHYq1Y4r6IE=\n"
//var public = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrDysnndm5BjfWlc4jaBqkRyf7rtpBAga2u14Fv1XGlLqa7swTuqVPinUBMGPXufII0NNv8C/b99ZYsrhZMNIkYhUuWeCsPDvsSjcdUhwuwGSnjWw2l2Q4z40o7s8AgeUSlEH1xRNrcZKzVQiT+jhxtl8KMpZWiLAZojLzp0NDdQIDAQAB\n"
//encrypt.setPublicKey(private)
encrypt.setPrivateKey(private)
//解码base64加密字符串
var randomStringEncodeByDecodeRsaPublicKeyWithBase64 = "RWRFbWZJQURublNZT2dlMzVwQ0RJTldqNUIrRTN3V3ZGYmxsR1BiQmQyaDNLS2xoTFhnK1FPRG1zNm9VSWZsSzZ5cUVHeFhndnN1dVI4ZTkzU3Njbko3ZVAweGF4VXExZFIrMnM0K1BicXo0SmxEOUNKWVdoeGVzVWpMQ2lvbnVrWEFqbTZMalMxZVl1ZWQvRDFpYlJMdFVPWXlxVzZEUE1Ed0xBL0NsSHJvPQ==\n";
var randomStringDecodeByDecodeRsaPublicKeyWithBase64 = window.atob(randomStringEncodeByDecodeRsaPublicKeyWithBase64).toString();
console.log("解码base64加密字符串:" + randomStringDecodeByDecodeRsaPublicKeyWithBase64)
//私钥解密字符串
var originRandomString = encrypt.decrypt(randomStringDecodeByDecodeRsaPublicKeyWithBase64);
console.log("原生字符串" + originRandomString)
//密码加字符串,AES对称加密,以原生字符串作密钥
//1.偏移值保持与后端相同
var iv = CryptoJS.enc.Utf8.parse("0123456789ABCDEF");
//2.原生字符串+密码 为内容,原生字符串作密钥,AES加密
var password = "123";
var aesEncrypt = CryptoJS.AES.encrypt(originRandomString+password, CryptoJS.enc.Utf8.parse(originRandomString),{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
//直接给这个给后端,返回的是base64
console.log("AES加密后aesEncrypt = %s"+aesEncrypt.toString())
/*console.log(aesEncrypt.iv.toString(CryptoJS.enc.Base64))*/
var aesDecrypt = CryptoJS.AES.decrypt(aesEncrypt, CryptoJS.enc.Utf8.parse(originRandomString) , {
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
console.log("AES解密后aesDecrypt = %s", aesDecrypt.toString(CryptoJS.enc.Utf8));
//base64编码
let decodeByBase64 = window.btoa(aesEncrypt);
console.log("base64编码AES加密字符串:" + decodeByBase64)
/* console.log(hex_to_bin(s))*/
/* function hex_to_bin(str) {
let hex_array = [{key:0,val:"0000"},{key:1,val:"0001"},{key:2,val:"0010"},{key:3,val:"0011"},{key:4,val:"0100"},{key:5,val:"0101"},{key:6,val:"0110"},{key:7,val:"0111"},
{key:8,val:"1000"},{key:9,val:"1001"},{key:'a',val:"1010"},{key:'b',val:"1011"},{key:'c',val:"1100"},{key:'d',val:"1101"},{key:'e',val:"1110"},{key:'f',val:"1111"}]
let value=""
for(let i=0;i<str.length;i++){
for(let j=0;j<hex_array.length;j++){
if(str.charAt(i).toLowerCase()== hex_array[j].key){
value = value.concat(hex_array[j].val)
break
}
}
}
console.log(value)
return value
}*/
</script>
</html>