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; } } }