Loading... # 引言 由于原有的处理器效率过低,从Python欲迁移到Java版,这里简单记录一下RSA的加解密以及分段的加解密操作方法。 # 生成&转换 ```shell openssl genrsa -out priv1.pem 4096 # 生成私钥 4096代表位数 openssl pkcs8 -topk8 -in priv.pem -out priv8.pem -nocrypt # 私钥 PKCS1 --> PKCS8 openssl rsa -in priv.pem -pubout -out pub.pem # 私钥生成公钥 ``` # 代码 <div class="tip inlineBlock share"> 如果使用openssl等工具生成的密钥,需`PKCS8`格式 代码中的密钥部分不包含`-----BEGIN RSA PRIVATE KEY-----`和`-----END RSA PRIVATE KEY-----`,需'掐头去尾' </div> ```java package top.zunmx.sc.algorithm; import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.HashMap; public class RSAUtil<T> { public static String RSA_ALGORITHM = "RSA"; private static final int KEY_SIZE = 1024; private static final int MAX_ENCRYPT_BLOCK = 117; private static final int MAX_DECRYPT_BLOCK = 128; private byte[] priv_key = Base64.getDecoder().decode("MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMlrJn/STaexYjxmyEShthFd0sluWy49tYQxLXhek2tqLDSf6QGhniO0FJQCdi0iR2Wws0z1FdJljZKYSO44wo4d81T7/oAdipScChrVRL8iDh3WveQ0H9shdRxhia8AqXgZxhZO9Z7kfwut81uuM8BbnJOrI41jFwjnWJhq4lRXAgMBAAECgYBcElUI/RNuYpGrVriZVuqpSaA/X+jiXGcLRIeqjGELKv+GFssmacCmRX1aoz1uKEtG2t07gpU1FiL/Lgm4i82y5aInWyyG1uD1h95+4Mg0h0J1TTOHa683jz5TVlZrvm/9PqQfhzxuucG6HjoHoyEyXVpJ2QiYbv+9qDWq5V9rgQJBAOmlImOwSgeIAmQZhrWLAVOMX3YgAmzhrHcc6upeJ/inCCgKPZPBnNUxeRCvj/AjcDg4yC7M+r8q08fVLaI0BOECQQDcsKpJPtRiVp6ERCDNgrLSbeEtQJz+0OlXjwPPlOypZfVh2n0Uc1ia3GZd/oMDFeOOl/HyAMy3tkxVId8lFkg3AkB3BTksgTxk88MMDPjTeDk3v1VNzmaN4rRBhUiiFU7VWvlLtFPD9igXbnlWp6hyUwsyiLJpLOA7C+0Qaicx7r/hAkAqywb6FPjR6MHsG9nQf9t0+mGDiNfogVH97HlssxAA+QhP5TID2SoBPWOMLmHxIzlw2P3NU2Je7TZ3+41tf5iZAkBmoiXs29LgRz1Q76XD0wiA1TbqQCCbiRCpznLMarBsYS1rPzBLTMfrOeJ4iY4LO/wBfzzIWE3j2TIzywT094Fh"); private byte[] pub_key = Base64.getDecoder().decode("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJayZ/0k2nsWI8ZshEobYRXdLJblsuPbWEMS14XpNraiw0n+kBoZ4jtBSUAnYtIkdlsLNM9RXSZY2SmEjuOMKOHfNU+/6AHYqUnAoa1US/Ig4d1r3kNB/bIXUcYYmvAKl4GcYWTvWe5H8LrfNbrjPAW5yTqyONYxcI51iYauJUVwIDAQAB"); public RSAUtil(String pubKey, String privKey) { this.pub_key = Base64.getDecoder().decode(pubKey); this.priv_key = Base64.getDecoder().decode(privKey); } public RSAUtil() { } public static HashMap<String, String> generatorKey() throws NoSuchAlgorithmException { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(KEY_SIZE); // 初始化密钥生成器,并指定密钥长度为 1024 位 KeyPair keyPair = keyGen.generateKeyPair(); // 生成密钥对 String pubKey = new String(Base64.getEncoder().encode((keyPair.getPublic().getEncoded()))); String privKey = new String(Base64.getEncoder().encode((keyPair.getPrivate().getEncoded()))); System.out.println("公钥:" + pubKey); System.out.println("私钥:" + privKey); HashMap<String, String> keys = new HashMap<>(); keys.put("pubKey", pubKey); keys.put("privKey", privKey); return keys; } public String encryptByPrivateKey(byte[] data) { try { //取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(this.priv_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); //生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return Base64.getEncoder().encodeToString(cipher.doFinal(data)); } catch (Exception e) { return null; } } public String encryptByPublicKey(byte[] data) { try { //实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); //初始化公钥,根据给定的编码密钥创建一个新的 X509EncodedKeySpec。 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(this.pub_key); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); //数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return Base64.getEncoder().encodeToString(cipher.doFinal(data)); } catch (Exception e) { return null; } } public byte[] decryptByPrivateKey(String data) { try { //取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(this.priv_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); //生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(Base64.getDecoder().decode(data)); } catch (Exception e) { return null; } } public byte[] decryptByPublicKey(String data) { try { //实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); //初始化公钥 //密钥材料转换 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(this.pub_key); //产生公钥 PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); //数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, pubKey); return cipher.doFinal(Base64.getDecoder().decode(data)); } catch (Exception e) { return null; } } private byte[] segmentDecrypt(byte[] encryptText, Cipher cipher) throws Exception { int inputLen = encryptText.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(encryptText, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptText, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] plainText = out.toByteArray(); out.close(); return plainText; } private String segmentEncrypt(byte[] plainTextArray, Cipher cipher) throws Exception { int inputLen = plainTextArray.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; int i = 0; byte[] cache; while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(plainTextArray, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(plainTextArray, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptText = out.toByteArray(); out.close(); return Base64.getEncoder().encodeToString(encryptText); } public String encryptSegmentByPrivateKey(T plainText) throws Exception { String name = plainText.getClass().getName(); byte[] plainTextArray = null; if (name.equals("java.lang.String")) { plainTextArray = ((String) plainText).getBytes(); } else { plainTextArray = (byte[]) plainText; } PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(this.priv_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return segmentEncrypt(plainTextArray, cipher); } public String encryptSegmentByPublicKey(T plainText) throws Exception { String name = plainText.getClass().getName(); byte[] plainTextArray = null; if (name.equals("java.lang.String")) { plainTextArray = ((String) plainText).getBytes(); } else { plainTextArray = (byte[]) plainText; } KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(this.pub_key); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return segmentEncrypt(plainTextArray, cipher); } public byte[] decryptSegmentByPrivateKey(String encryptTextHex) throws Exception { byte[] encryptText = Base64.getDecoder().decode(encryptTextHex); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(this.priv_key); KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return segmentDecrypt(encryptText, cipher); } public byte[] decryptSegmentByPublicKey(String encryptTextHex) throws Exception { byte[] encryptText = Base64.getDecoder().decode(encryptTextHex); KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(this.pub_key); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return segmentDecrypt(encryptText, cipher); } } ``` ```java public class Main { public static void main(String[] args) throws Exception { HashMap<String, String> keys = RSAUtil.generatorKey();// 生成密钥 RSAUtil rsaUtil = new RSAUtil(keys.get("pubKey"), keys.get("privKey")); // 使用新生成的密钥 // RSAUtil rsaUtil = new RSAUtil(); byte[] text = new byte[]{97, 98, 99}; // 要加密的数据,字节数组 String enc = rsaUtil.encryptByPublicKey(text); byte[] dec = rsaUtil.decryptByPrivateKey(enc); System.out.println("公钥加密: " + enc); System.out.println("私钥解密: " + new String(dec)); String s = new String("Hello World"); // 要加密的数据,字符串 enc = rsaUtil.encryptByPrivateKey(s); dec = rsaUtil.decryptByPublicKey(enc); System.out.println("私钥加密: " + enc); System.out.println("公钥解密: " + new String(dec)); // 长字符串 String s1 = new String("Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,Hello World,"); // 要加密的数据 enc = rsaUtil.encryptSegmentByPublicKey(s1); dec = rsaUtil.decryptSegmentByPrivateKey(enc); System.out.println("公钥加密: " + enc); System.out.println("私钥解密: " + new String(dec)); // 长字节数组 byte[] s2 = new byte[]{97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99, 97, 98, 99}; // 要加密的数据,字节数组 enc = rsaUtil.encryptSegmentByPrivateKey(s2); dec = rsaUtil.decryptSegmentByPublicKey(enc); System.out.println("私钥加密: " + enc); System.out.println("公钥解密: " + new String(dec)); } } ``` ![image.png](https://www.zunmx.top/usr/uploads/2023/12/341694748.png) # 特性 RSA:非对称加密算法 公钥:公开的密钥 私钥:私有的密钥 加密解密:公钥加密一定是私钥解密,私钥加密一定是公钥解密 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏