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