RSA非对称加密
java RSA 分段分组加密
文中公钥和私钥都从resource下去加载的,你可以直接使用字符串也是可以的
一般情况使用公钥加密,私钥解密
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.core.io.ClassPathResource; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import java.io.*; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; /** * @author Mr.Fang * @version 1.0 * @description: RAS 非对称加密解密 2048 * @date 2022/5/12 11:06 */ public class RSAUtil { /** * 1024 加密最大块 117 * 最大文件加密块 2048 不能超过 245 */ private static final int MAX_ENCRYPT_BLOCK = 245; /** * 1024 解密最大块 128 * 最大文件解密块 2048 不能超过 256 */ private static final int MAX_DECRYPT_BLOCK = 256; /** * 字符集 */ private static final String CHAR_SET_NAME = "UTF-8"; /** * 加密类型 */ private static final String ENCRYPT_TYPE = "RSA"; /** * description: 创建秘钥对 公钥和私钥 * create by: Mr.Fang * * @param keySize: 秘钥字节数 * @date: 2022/5/17 10:33 */ public RSAUtil.RSAKey createKey(int keySize) { try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ENCRYPT_TYPE); keyPairGenerator.initialize(keySize); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); String publicKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded()); PrivateKey privateKey = keyPair.getPrivate(); String privateKeyStr = Base64.getEncoder().encodeToString(privateKey.getEncoded()); return new RSAUtil.RSAKey(privateKeyStr, publicKeyStr); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } @Data @NoArgsConstructor @AllArgsConstructor public class RSAKey { private String privateKey; private String publicKey; } /** * description: 从 resource 加载公钥 * create by: Mr.Fang * * @return: java.security.interfaces.RSAPublicKey * @date: 2022/5/17 9:27 */ private static RSAPublicKey getPublicKey() { try { ClassPathResource resource = new ClassPathResource("publicKey"); InputStream inputStream = null; try { inputStream = resource.getInputStream(); } catch (IOException e) { e.printStackTrace(); } //将流转为字符串 String string = readToString(inputStream); KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_TYPE); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getMimeDecoder().decode(string)); RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec); return publicKey; } catch (NoSuchAlgorithmException var4) { var4.printStackTrace(); } catch (InvalidKeySpecException var5) { var5.printStackTrace(); } return null; } /** * description: 从 resource 加载私钥 * create by: Mr.Fang * * @return: java.security.interfaces.RSAPrivateKey * @date: 2022/5/17 9:12 */ private static RSAPrivateKey getPrivateKey() { ClassPathResource resource = new ClassPathResource("privateKey"); try (InputStream inputStream = resource.getInputStream()) { String privateKeyStr = readToString(inputStream); KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_TYPE); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(privateKeyStr)); RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec); return privateKey; } catch (NoSuchAlgorithmException var4) { var4.printStackTrace(); } catch (InvalidKeySpecException var5) { var5.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * description: 输入流转字符串 * create by: Mr.Fang * * @param inputStream: 输入流 * @return: java.lang.String * @date: 2022/5/18 8:53 */ public static String readToString(InputStream inputStream) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHAR_SET_NAME)); StringBuffer sb = new StringBuffer(); for (String s = reader.readLine(); s != null; s = reader.readLine()) { sb.append(s); } String toString = sb.toString(); return toString; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * description: 分段公钥加密 * create by: Mr.Fang * * @param inputStr: 待加密数据 * @return: java.lang.String * @date: 2022/5/17 9:26 */ public static String publicEncrypt(String inputStr) { try { // 获取 cipher 加密对象 Cipher cipher = Cipher.getInstance(ENCRYPT_TYPE); // 获取公钥 RSAPublicKey rsaPublicKey = getPublicKey(); // 初始化加密对象 第一个参数加密模式,第二个参数公钥 cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); // 加密字符串转字节数组 byte[] bytes = inputStr.getBytes(CHAR_SET_NAME); // 字节长度 int length = bytes.length; // 偏移 int offset = 0; // 当前下标 int i = 0; // 创建字节输出流 ByteArrayOutputStream byOutput = new ByteArrayOutputStream(); while (length - offset > 0) { // 存放每次加密后的字节 byte[] cache; // if (length - offset > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(bytes, offset, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(bytes, offset, length - offset); } // 写入字节流 byOutput.write(cache); i++; // 自增 offset = MAX_ENCRYPT_BLOCK * i; // 偏移 } byOutput.flush(); // 刷新 byOutput.close(); // 关闭字节流 // 转字节数组 byte[] byteArray = byOutput.toByteArray(); // base64 编码 return Base64.getEncoder().encodeToString(byteArray); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * description: 分段私钥解密 * create by: Mr.Fang * * @param inputStr: 密文 * @return: java.lang.String * @date: 2022/5/17 9:20 */ public static String privateDecrypt(String inputStr) throws Exception { // 获取 cipher 加密对象 Cipher cipher = Cipher.getInstance(ENCRYPT_TYPE); //获取私钥 PrivateKey privateKey = getPrivateKey(); // 初始化 cipher 对象,第一个参数解密模式,第二个参数解密秘钥 cipher.init(Cipher.DECRYPT_MODE, privateKey); // base64 解码 byte[] bytes = Base64.getDecoder().decode(inputStr); // 字节长度 int length = bytes.length; // 偏移 int offset = 0; // 当前下标 int i = 0; // 创建字节输出流 ByteArrayOutputStream byOutput = new ByteArrayOutputStream(); while (length - offset > 0) { // 存放每次机密后的字节 byte[] cache; // if (length - offset > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(bytes, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(bytes, offset, length - offset); } // 写入字节流 byOutput.write(cache); i++; // 自增 offset = MAX_DECRYPT_BLOCK * i; // 偏移 } byOutput.flush(); // 刷新 byOutput.close(); // 关闭字节流 // 转字节数组 byte[] byteArray = byOutput.toByteArray(); return new String(byteArray, CHAR_SET_NAME); } }
测试结果
哇!又赚了一天人民币