package test;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class ParseUtil {
/**
* AES算法名称
*/
private final static String AES = "AES";
/**
* 算法
*/
public final static String ALGORITHM = "RSA";
/**
* 哈希算法
*/
public final static String HASH = "SHA";
//
/**
* 签名哈希算法
*/
public final static String SHA1WITHRSA = "SHA1withRSA";
public static void main(String[] args) {
// 用户系统持有的秘钥
String userPrivate = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJkxG9Xo1O/bnqZWTt4HgjNxlDgnNjFXm9ZJbxTOpoao6pCGcZzT1hHHUJSoMrYlQR3/qkjUwEr72G71aBdTa7KXATVs0ca2IfOA9HxNV13XlpikwDGzL0fERlRAj3eCPM6ykouOpLSoXZBtIS2dw0tlHn14ufWcmHVOyuhkPgIfAgMBAAECgYEAjFyCtKxw7pS7+Ix8FtOqaJhYxlqnPO6Yyu7d6KKv0hJTWbjVwGwYaJHHM24piNr5nxLyY2kMB6hZ1tDkXvsAYWZk3R4sf9t0+Qrwh3xwM2OhWpUlyeTCA16fxCloSVLrhiwvLZmjinVKybYTNUIvg7bFoVDK+YCOjoLvA+38agECQQDTt/pGhOudiHEVt+0QMGf1HvMLZWFjtxPQulVgmHXL95hh1y6Qyj39Q58xOQupig6rUcqOJE/4hLS8YXyQzX/PAkEAuTtv7s2DIwP4J0GqQ4gG69xEb/LLWqx8qajn2SinSH8V4bpd1z2O6gnqrpWdqvGFab86BGJxrq8TPRbJfnIcsQJBALcdmdbiYhMXjo91TBHDfDaS9S13GvuuvfG7J9rrIn8uf9qnzXunoGPr18UwDLkvUi61CFdWauCMjvGb86weQRsCQArbKe9ECjiGJgge+BynH0i5iyVIhJSW4WOMK7J1iIBeOmkVZCSWTgb3d9KtoCUBrMEK3Rqermz/g9AjwsFvbLECQEVekV8lUacnXehwU+wvNw+rD53E6cW7ntS142g4oH0TulASSi8w1IMTBrgE3OfPsoKQM67Tm8wzTiSubnMFCog=";
String systemPubic = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnuJEgORIe4jROGM7MlKYqBT+nCid95oUoQYHyv0wXkxJehBCveqgxlC0Ql1MsKT96wz8aY2mduwCtyRyhYB+pyj6kLj/hkSk83p5jA5ylw/ATJ7C1v0tCW64qZ/u3K+Nw/yqDNTpeP8/9DoIsD4rOnkHbTckisbtijIo88sAyMQIDAQAB";
// 系统持有的秘钥
String systemPrivate = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKe4kSA5Eh7iNE4YzsyUpioFP6cKJ33mhShBgfK/TBeTEl6EEK96qDGULRCXUywpP3rDPxpjaZ27AK3JHKFgH6nKPqQuP+GRKTzenmMDnKXD8BMnsLW/S0Jbripn+7cr43D/KoM1Ol4/z/0OgiwPis6eQdtNySKxu2KMijzywDIxAgMBAAECgYAEBo0NLfF+ZkWFHllQVb0LQyb89mRuRCssBS5+ShMkebY2KItR+uqwjfLq9AbeB3trkeYg1wQA8i0Y/ru+L9VyrqqEntqoWtoJtFc968/qu+Qt28gn/t85nEnchlvc1J7oSpdpNRfLxSjAqQ0xz7/dXcBDH9V3RHik+CTqSB06xQJBAP9+c+oCXEjUJzoR+WcDirA7kFnlk0Y3p+QslRvTEpLq9w1f26PQj/2Jqdu1/kUyzoA4B5esIcqWUUeCXmSv0JsCQQCoDZvxrsIRGPDM6xaaLugBfd5vuUTOztiNZm9XfOosn8s8imcJ2FUu0qRHKhsVbCmEd2AlVfLBE5T3QbzcllcjAkEAipYwEAY5wrN5l7E6RJuSNigJFApIibUU19srAo3KrHDRk6qkfEZcZJ2wymH8y9JUWw6JZ8dSCQ7ihdR8mUcY8wJAHOOKBTfngIzrCC75ibO6ilca39XXcD26mEQdq8p7bwRhKZ0ZLWYU7qGjP+CLG1mmoXDsBD8MJgi5uO+CCeGGRQJAA8kbFl1eSFnI367JPLZBd8GEvLmmw7N1NeVz7iJ30bYJ/5OOFWRxKkeTastTWJlkIvEK/srwJKQyk4tNZ67tcg==";
String userPublic = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZMRvV6NTv256mVk7eB4IzcZQ4JzYxV5vWSW8UzqaGqOqQhnGc09YRx1CUqDK2JUEd/6pI1MBK+9hu9WgXU2uylwE1bNHGtiHzgPR8TVdd15aYpMAxsy9HxEZUQI93gjzOspKLjqS0qF2QbSEtncNLZR59eLn1nJh1TsroZD4CHwIDAQAB";
//加密userId
String userId = "3";
byte[] bytes = RSAUtils.sign(Base64.decodeBase64(userPrivate), RSAUtils.mdigestSHA(userId.getBytes()));
String cryptUserId = Base64.encodeBase64String(bytes);//加密后的userId
//用户系统加密数据示例
String cyptContent = encryptSample(userPrivate, systemPubic, "用户加密测试数据",Long.valueOf(userId));
//用户系统解密数据示例
String data =encryptSample(systemPrivate, userPublic, "用户解密测试数据",Long.valueOf(userId));//系统加密数据
String plainContent = decryptSample(systemPubic, userPrivate, data);//用户系统解密
System.out.println("加密内容:" + cyptContent);
System.out.println("解密内容:" + plainContent);
}
/**
* 生成密钥
*
* @return
*/
public static byte[] initkey() {
SecretKey secretKey = null;
try {
KeyGenerator keyGen = KeyGenerator.getInstance(AES);
keyGen.init(128);
secretKey = keyGen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return secretKey.getEncoded();
}
/**
* AES加密
*
* @param data
* @param key
* @return
*/
public static byte[] encrypt(byte[] data, byte[] key) {
byte[] cipherBytes = null;
try {
SecretKey secretKey = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
cipherBytes = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return cipherBytes;
}
/**
* AES解密
*
* @param data
* @param key
* @return
*/
public static byte[] decrypt(byte[] data, byte[] key) {
byte[] plainBytes = null;
try {
SecretKey secretKey = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
plainBytes = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return plainBytes;
}
/**
* 使用RSA公钥加密数据
*
* @param pubKeyInByte 打包的byte[]形式公钥
* @param data 要加密的数据
* @return 加密数据
*/
public static byte[] encryptByRSA(byte[] pubKeyInByte, byte[] data) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyInByte);
PublicKey publicKey = keyFactory.generatePublic(pubSpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 用RSA私钥解密
*
* @param privateKeyInByte 私钥打包成byte[]形式
* @param data 要解密的数据
* @return 解密数据
*/
public static byte[] decryptByRSAPrivateKey(byte[] privateKeyInByte, byte[] data) {
try {
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(
privateKeyInByte);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(privSpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 生成数字摘要
* @param source
* @return
*/
public static byte[] mdigestSHA(byte[] source) {
try {
MessageDigest thisMD = MessageDigest.getInstance(HASH);
byte[] digest = thisMD.digest(source);
return digest;
} catch (Exception e) {
return null;
}
}
/**
* 使用私钥加密数据(发送数据采用私钥签名)
* 用一个已打包成byte[]形式的私钥加密数据,即数字签名
*
* @param privateKeyInByte 打包成byte[]的私钥
* @param source 要签名的数据,一般应是数字摘要
* @return 签名 byte[]
*/
public static byte[] sign(byte[] privateKeyInByte, byte[] source) {
try {
PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(privateKeyInByte);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(privateSpec);
Signature signature = Signature.getInstance(SHA1WITHRSA);
signature.initSign(privateKey);
signature.update(source);
return signature.sign();
} catch (Exception e) {
return null;
}
}
/**
* 验证签名(接收数据使用发送方公钥验证签名)
*
* @param publicKeyInByte 二进制公钥
* @param source 源数据
* @param sign 数字签名
* @return 验证结果
*/
public static boolean verify(byte[] publicKeyInByte, byte[] source, byte[] sign) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
Signature signature = Signature.getInstance(SHA1WITHRSA);
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(publicKeyInByte);
PublicKey publicKey = keyFactory.generatePublic(pubSpec);
signature.initVerify(publicKey);
signature.update(source);
return signature.verify(sign);
} catch (Exception e) {
return false;
}
}
/**
* 加密示例
* @param userPrivateKey
* @param sysPublicKey
* @param content
* @return
*/
public static String encryptSample(String userPrivateKey, String sysPublicKey, String content,Long userId) {
SendData data = new SendData();
//生成AES密钥
byte[] AESKeyBytes = ParseUtil.initkey();
//RSA公钥加密AES密钥
byte[] cipherKeyBytes = ParseUtil.encryptByRSA(Base64.decodeBase64(sysPublicKey), AESKeyBytes);
//加密文本
byte[] cipherTextBytes = ParseUtil.encrypt(content.getBytes(), AESKeyBytes);
//签名(通过加密文本获取数字摘要,然后对摘要通过用户私钥进行签名)
byte[] signBytes = ParseUtil.sign(Base64.decodeBase64(userPrivateKey), ParseUtil.mdigestSHA(cipherTextBytes));
data.setAESKeyString(Base64.encodeBase64String(cipherKeyBytes));
data.setCyptContent(Base64.encodeBase64String(cipherTextBytes));
data.setSign(Base64.encodeBase64String(signBytes));
data.setUserId(userId);
return JsonUtil.toJson(data);
}
/**
* 解密示例
* @param userPublicKey
* @param sysPrivateKey
* @param cyptContent
* @return
*/
public static String decryptSample(String userPublicKey, String sysPrivateKey, String cyptContent) {
ReceiveData data = JsonUtil.fromJson(cyptContent, ReceiveData.class);
//从base64中获取字节数组
//RSA公钥加密AES密钥
byte[] cipherKeyBytes = Base64.decodeBase64(data.getAESKeyString());
//加密文本
byte[] cipherTextBytes = Base64.decodeBase64(data.getCyptContent());
//签名(通过加密文本获取数字摘要,然后对摘
byte[] signBytes = Base64.decodeBase64(data.getSign());
//验证签名
boolean isValid = ParseUtil.verify(Base64.decodeBase64(userPublicKey),
ParseUtil.mdigestSHA(cipherTextBytes),
signBytes);
if (isValid) {
//RSA私钥解密AES密钥
byte[] AESKeyBytes = decryptByRSAPrivateKey(Base64.decodeBase64(sysPrivateKey), cipherKeyBytes);
if (AESKeyBytes != null) {
byte[] plainText = decrypt(cipherTextBytes, AESKeyBytes);
return new String(plainText);
}
}
return null;
}
/**
* json转换工具
*/
public static class JsonUtil {
private static final ObjectMapper JSON_MAPPER;
static {
JSON_MAPPER = new ObjectMapper();
JSON_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public static String toJson(Object obj) {
try {
return JSON_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
public static <T> T fromJson(String json, Class<T> cla) {
try {
return JSON_MAPPER.readValue(json, cla);
} catch (Exception e) {
e.printStackTrace();
//LOG.error("error on fromJson", e);
}
return null;
}
}
/**
* 企业方接收数据格式
*/
public static class ReceiveData {
private final String status = "success";
private String sign;
private String cyptContent;
private String AESKeyString;
public String getStatus() {
return status;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getCyptContent() {
return cyptContent;
}
public void setCyptContent(String cyptContent) {
this.cyptContent = cyptContent;
}
public String getAESKeyString() {
return AESKeyString;
}
public void setAESKeyString(String AESKeyString) {
this.AESKeyString = AESKeyString;
}
}
/**
* 企业方发送数据格式
*/
public static class SendData {
private Long userId;
private String sign;
private String cyptContent;
private String AESKeyString;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getCyptContent() {
return cyptContent;
}
public void setCyptContent(String cyptContent) {
this.cyptContent = cyptContent;
}
public String getAESKeyString() {
return AESKeyString;
}
public void setAESKeyString(String AESKeyString) {
this.AESKeyString = AESKeyString;
}
}
}