package com.example.study.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class SecretUtil {
public static final String CHARSET_UTF = "UTF-8";
public static final String CHARSET_GBK = "GBK";
// 设置公钥,私钥长度
public static final int KEY_SIZE = 2048;
public static final String PUBLIC_KEY_NAME = "publicKey";
public static final String PRIVATE_KEY_NAME = "privateKey";
// 定义加密算法,有DES、DESede(即3DES)、Blowfish
public static final String ALGORITHM_3DES = "DESede";
public static final String ALGORITHM_RSA = "RSA";
public static final String SIGNATURE_ALGORITHM_SHA256 = "SHA256withRSA";
// transformation的格式是“算法/工作模式/填充模式”
public static final String TRANSFORMATION_ECB = "DESede/ECB/PKCS5Padding";
public static final String TRANSFORMATION_CBC = "DESede/CBC/PKCS5Padding";
// 默认加密密码
public static final String PASSWORD_CRYPT_KEY = "2012PinganVitality075522628888ForShenZhenBelter075561869839";
/**
* 3DES 加密
*
* @param key 密钥
* @param content 加密内容
* @return 密文
*/
public static String des3Encrypt(String key, String content) {
try {
SecretKey secretKey = build3DesKey(key);
Cipher cipher = Cipher.getInstance(TRANSFORMATION_ECB);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] res = cipher.doFinal(content.getBytes(CHARSET_UTF));
//encodeBase64会对字符串3位一组自动补全,因而最后可能会出现 == 或者 =
return new String(Base64.encodeBase64(res), CHARSET_UTF);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 3DES 加密
*
* @param content 明文
* @return 密文
*/
public static String des3Encrypt(String content) {
return des3Encrypt(PASSWORD_CRYPT_KEY, content);
}
/**
* 3DES 解密
*
* @param key 密钥
* @param content 解密内容
* @return 明文
*/
public static String des3Decode(String key, String content) {
try {
SecretKey secretKey = build3DesKey(key);
Cipher cipher = Cipher.getInstance(TRANSFORMATION_ECB);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] res = cipher.doFinal(Base64.decodeBase64(content.getBytes(CHARSET_UTF)));
return new String(res, CHARSET_UTF);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 3DES 解密
*
* @param content 密文
* @return 明文
*/
public static String des3Decode(String content) {
return des3Decode(PASSWORD_CRYPT_KEY, content);
}
/**
* 根据字符串生成密钥字节数组
*
* @param keyStr 密钥字符串
* @return 密钥
* @throws Exception
*/
public static SecretKey build3DesKey(String keyStr) throws Exception {
byte[] key = new byte[24]; //声明一个24位的字节数组,默认里面都是0
byte[] temp = keyStr.getBytes(CHARSET_UTF); //将字符串转成字节数组
/*
* 执行数组拷贝
* 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);
}
//DESedeKeySpec会帮你生成24位秘钥,key可以是任意长度
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_3DES);
SecretKey secretKey = keyFactory.generateSecret(spec);
return secretKey;
}
/**
* 生成公、私钥
*
* @return map
*/
public static Map<String, String> generateRsaKeys() {
Map<String, String> keyPairMap = new HashMap<String, String>();
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_RSA);
keyPairGenerator.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
//获取公、私钥值
String publicKeyValue = Base64.encodeBase64String(publicKey.getEncoded());
String privateKeyValue = Base64.encodeBase64String(privateKey.getEncoded());
//存入
keyPairMap.put(PUBLIC_KEY_NAME, publicKeyValue);
keyPairMap.put(PRIVATE_KEY_NAME, privateKeyValue);
} catch (Exception e) {
e.printStackTrace();
}
return keyPairMap;
}
/**
* 解码 PublicKey
*
* @param key
* @return
*/
public static PublicKey getPublicKey(String key) {
try {
byte[] byteKey = Base64.decodeBase64(key);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
return keyFactory.generatePublic(x509EncodedKeySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解码 PrivateKey
*
* @param key
* @return
*/
public static PrivateKey getPrivateKey(String key) {
try {
byte[] byteKey = Base64.decodeBase64(key);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 签名
*
* @param key 私钥
* @param requestData 请求参数
* @return
*/
public static String sign(String key, String requestData) {
String signature = null;
try {
PrivateKey privateKey = getPrivateKey(key);
Signature Sign = Signature.getInstance(SIGNATURE_ALGORITHM_SHA256);
Sign.initSign(privateKey);
Sign.update(requestData.getBytes());
signature = Base64.encodeBase64String(Sign.sign());
System.out.println("===签名结果:" + signature);
} catch (Exception e) {
e.printStackTrace();
}
return signature;
}
/**
* 验签
*
* @param key 公钥
* @param requestData 请求参数
* @param signature 签名
* @return
*/
public static boolean verifySign(String key, String requestData, String signature) {
boolean verifySignRes = false;
try {
PublicKey publicKey = getPublicKey(key);
Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM_SHA256);
verifySign.initVerify(publicKey);
verifySign.update(requestData.getBytes());
verifySignRes = verifySign.verify(Base64.decodeBase64(signature));
System.out.println("===验签结果:" + verifySignRes);
} catch (Exception e) {
e.printStackTrace();
}
return verifySignRes;
}
/**
* 构建签名数据, 将 Map 转成 key1=value1&key2=value2...(按照字段名的ASCII 码从小到大排序,即字典序)
* @param params 请求参数
* @return
*/
public static String buildSignData(Map<String,Object> params){
StringBuilder sb = new StringBuilder();
// 将参数以参数名的字典升序排序
Map<String, Object> sortParams = new TreeMap<>(params);
// 遍历排序的字典,并拼接"key=value"格式
for (Map.Entry<String, Object> entry : sortParams.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
if (!sortParams.isEmpty()) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
public static void main(String[] args) {
String key = "123456";
String msg = "3DES加密解密案例";
System.out.println("【加密前】:" + msg);
//加密
String cipherText = SecretUtil.des3Encrypt(key, msg);
System.out.println("【加密后】:" + cipherText);
//解密
String msgText = SecretUtil.des3Decode(key, cipherText);
System.out.println("【解密后】:" + msgText);
//签名 验签
Map<String, String> keyPairMap = generateRsaKeys();
System.out.println("生成公、私钥测试:"+keyPairMap);
String publicKey = keyPairMap.get(PUBLIC_KEY_NAME);
String privateKey = keyPairMap.get(PRIVATE_KEY_NAME);
System.out.println("===开始RSA公、私钥测试===");
String str = "alpha=001&beta=002&gamma=003";
String sign = sign(privateKey, str);
verifySign(publicKey, str, sign);
}
}
非对称加密类(RSA)
最新推荐文章于 2022-09-16 17:29:35 发布