赞
踩
实际工作中经常遇到与第三方进行数据交互的场景,这个时候,处于安全的考虑,通常会对数据进行加密,RSA+BASE64是常见的加密验签的算法组合。所谓RSA就是一种非对称的加密算法,他会生成一组秘钥公钥
、私钥
公钥负责加密和验签的工作
。公钥是给对方使用的,对方用我方的公钥 对我方传输到对方的数据 进行验签,我方利用对方的公钥,对我方传输到对方的数据进行加密。私钥负责解密和加签工作
。私钥是给自己用的,己方利用私钥 对我方传递到对方的数据进行加签,对对方传递到我方的数据进行解密。需要如下依赖
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
public class RSADemo { /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * 获取秘钥对 * @return * @throws Exception */ public static KeyPair getKeyPair() throws Exception { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(1024); return generator.generateKeyPair(); } /** * 获取私钥 * @param privateKey * @return * @throws Exception */ public static PrivateKey getPrivateKey(String privateKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey); return keyFactory.generatePrivate(keySpec); } /** * 获取公钥 * @param publicKey * @return * @throws Exception */ public static PublicKey getPublicKey(String publicKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey); return keyFactory.generatePublic(keySpec); } /** * RSA 加密 * @param data * @param publicKey * @return * @throws Exception */ public static String encrypt(String data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int inputLen = data.getBytes().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.getBytes(), offset, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串 加密后的字符串 return new String(Base64.encodeBase64String(encryptedData)); } /** * RSA解密 * @param data * @param privateKey * @return * @throws Exception */ public static String decrypt(String data, PrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] dataBytes = Base64.decodeBase64(data); int inputLen = dataBytes.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(dataBytes, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(dataBytes, offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); // 解密后的内容 return new String(decryptedData, "UTF-8"); } /** * 签名 * @param data * @param privateKey * @return * @throws Exception */ public static String sign(String data, PrivateKey privateKey) throws Exception { byte[] keyBytes = privateKey.getEncoded(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey key = keyFactory.generatePrivate(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(key); signature.update(data.getBytes()); return new String(Base64.encodeBase64(signature.sign())); } /** * 验签 * @param srcData * @param publicKey * @param sign * @return * @throws Exception */ public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception { byte[] keyBytes = publicKey.getEncoded(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(key); signature.update(srcData.getBytes()); return signature.verify(Base64.decodeBase64(sign.getBytes())); } public static void main(String[] args) { try { // 生成密钥对 KeyPair keyPair = getKeyPair(); String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())); String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())); System.out.println("私钥:" + privateKey); System.out.println("公钥:" + publicKey); //公钥加密 私钥解密 String data = "我是原始数据"; String encrptData = encrypt(data, keyPair.getPublic()); //利用公钥加密 System.out.println("加密后数据 = " + encrptData); System.out.println("解密后数据 = " + decrypt(encrptData, keyPair.getPrivate())); //利用私钥解密 String sign = sign(data, keyPair.getPrivate()); //私钥加签 System.out.println("验签结果 = " + verify(data, keyPair.getPublic(), sign)); //验签 //实际工作中更多的是跟第三方进行交互 需要与第三方交换公钥,对于己方来说 利用第三方的公钥验签, 利用己方的私钥解密 //第三方利用己方的公钥加密 利用自己(第三方自己)的私钥加签 } catch (Exception e) { e.printStackTrace(); System.out.print("加解密异常"); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。