RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
通过公钥加密信息,通过私钥解密信息;场景如下:A服务器通过一套秘钥中的公钥加密信息,将加密后的信息传给服务器B,服务B拿到加密后的信息,用该秘钥中的私钥进行解密获取到正确信息;达到服务器安全通信目的;
1.该工具类所需要的jar包
import org.apache.tomcat.util.codec.binary.Base64; import java.io.FileOutputStream; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException;
2.生成公钥私钥
public static void generateKey() { try { // 基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器,密钥大小为1024位 keyPairGen.initialize(512); // 最小值是512,一般设置值为1024,该值越大加密信息越安全,对计算机消耗也越大 //生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); //得到私钥 RSAPrivateKey RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //得到公钥 RSAPublicKey RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("私钥:" + Base64.encodeBase64String(privateKey.getEncoded())); System.out.println("公钥:" + Base64.encodeBase64String(publicKey.getEncoded())); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
3.将公钥的字符串转成PublicKey公钥对象
/** * @Description 根据字符串生产公钥 * @return java.security.PublicKey * @throws @Author zhanglei * @Date 14:25 2019/4/29 * @Param [key] **/ public static PublicKey getPublicKey(String publicKeys) throws Exception { byte[] keyBytes; keyBytes = Base64.decodeBase64(publicKeys); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; }
4.将私钥字符串转成PrivateKey对象
/** * String转私钥PrivateKey * @param * @return * @throws Exception */ public static PrivateKey getPrivateKey(String privateKeys) throws Exception { byte[] keyBytes; keyBytes = Base64.decodeBase64(privateKeys); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; }
5.加密
public byte[] encrypt(RSAPublicKey publicKey, byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { if (publicKey != null) { // Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); // 根据公钥,对Cipher对象进行初始 cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; }
6.解密
public byte[] decrypt(RSAPrivateKey privateKey, byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { if (privateKey != null) { // Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); // 根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; }
7. 将byte数组与字符串之间转换
(由于加密机密后都是返回byte数组,直接用new String(byte[])会导致其中数组中负数信息转译,导致数据无法还原,即此处通过Base64工具来转换)
/** * Sring转byte数组 */ public static byte[] stringToByte(String msg) { byte[] msgByte = Base64.decodeBase64(msg); return msgByte; } /** * byte数组转字符串 */ public static String byteToString(byte[] bytes) { String msg = Base64.encodeBase64String(bytes); return msg; }
具体该文件可访问如下地址:https://github.com/zlAdmin/didactic-enigma/blob/master/MapDemo/src/main/java/com/zl/unit/printunit/EncrypRSA.java