JAVA RSA PKCS1 分段加解密

pom.xml文件

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.64</version>
</dependency>
<!-- Feb, 2011 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk16</artifactId>
<version>1.46</version>
</dependency>
<!-- Oct, 2019 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.64</version>
</dependency>

Code

package cn.wecuit.utils;

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAUtils {

/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;

/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;

public static String encryptRSAByPubKey(String str, String publicKey) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher rsa = Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “BC”);
rsa.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey)); //getPrivateKey(privateKey):将privateKey转成pkcs1的密文形式

byte[] data = str.getBytes();
int inputLen = data.length;
int offset = 0;
byte[] cache;
int i = 0;
ByteArrayOutputStream out = new ByteArrayOutputStream();
//分段加密 参考:https://www.cnblogs.com/duanjt/p/11459600.html
while(inputLen -offset > 0){
if(inputLen – offset > MAX_ENCRYPT_BLOCK)
cache = rsa.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
else
cache = rsa.doFinal(data, offset, inputLen – offset);
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_ENCRYPT_BLOCK;
}
String result = new String(Base64.getEncoder().encode(out.toByteArray()));
out.close();
return result;
}
public static String decryptRSAByPriKey(String str, String privateKey) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher rsa = Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “BC”);
rsa.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey)); //getPrivateKey(privateKey):将privateKey转成pkcs1的密文形式

byte[] data = Base64.getDecoder().decode(str);
int inputLen = data.length;
int offset = 0;
byte[] cache;
int i = 0;
ByteArrayOutputStream out = new ByteArrayOutputStream();
//分段加密
while(inputLen -offset > 0){
if(inputLen – offset > MAX_DECRYPT_BLOCK)
cache = rsa.doFinal(data, offset, MAX_DECRYPT_BLOCK);
else
cache = rsa.doFinal(data, offset, inputLen – offset);
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_DECRYPT_BLOCK;
}
String result = out.toString(“UTF-8”);
out.close();
return result;
}

/**
* 参考: https://blog.csdn.net/weixin_43303530/article/details/111479748
* @param privateKey
* @return
* @throws Exception
*/
private static PrivateKey getPrivateKey(String privateKey) throws Exception {
String privKeyPEMNew = privateKey.replaceAll(“\\n”, “”)
.replace(“—–BEGIN PRIVATE KEY—–“, “”)
.replace(“—–END PRIVATE KEY—–“, “”);
byte[] e = Base64.getDecoder().decode(privKeyPEMNew); //base64无法解析换行符,-等特殊符号
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(e);
RSAPrivateKey pkcs1Key = RSAPrivateKey.getInstance(pki.parsePrivateKey());
//RSAPrivateKeyStructure pkcs1Key = RSAPrivateKeyStructure.getInstance(pki.parsePrivateKey());
//byte[] pkcs1Bytes = pkcs1Key.getEncoded();
// 读取 PKCS#1的私钥
//RSAPrivateKeyStructure asn1PrivateKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(pkcs1Bytes));
//RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(asn1PrivateKey.getModulus(),asn1PrivateKey.getPrivateExponent()); 此处注释的为过时方法,同样可以完成所需的效果
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(pkcs1Key.getModulus(),pkcs1Key.getPrivateExponent());
// 实例化KeyFactory对象,并指定 RSA 算法
KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);
// 获得 PrivateKey 对象
return keyFactory.generatePrivate(rsaPrivateKeySpec);
}

/**
*
* 参考:https://blog.csdn.net/chaiqunxing51/article/details/52116433?locationNum=3&fps=1
* @param publicKey
* @return
* @throws Exception
*/
private static PublicKey getPublicKey(String publicKey) throws Exception {
String pubKeyPEMNew = publicKey.replaceAll(“\\n”, “”)
.replace(“—–BEGIN PUBLIC KEY—–“, “”)
.replace(“—–END PUBLIC KEY—–“, “”);
byte[] e = Base64.getDecoder().decode(pubKeyPEMNew); //base64无法解析换行符,-等特殊符号
// RSAPublicKey pki = RSAPublicKey.getInstance(e);
// RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(pki.getModulus(), pki.getPublicExponent());
// // 实例化KeyFactory对象,并指定 RSA 算法
// KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);

X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(e);
KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);
return keyFactory.generatePublic(pubX509);

// 获得 PrivateKey 对象
// return keyFactory.generatePublic(rsaPublicKeySpec);
}

}

测试

package cn.wecuit.test;

import cn.wecuit.utils.RSAUtils;
import org.junit.Assert;
import org.junit.Test;

public class TestRSA {
static String privateKey = “—–BEGIN PRIVATE KEY—–\n” +
“MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBALKFyImIYEg6vhNe\n” +
“iNLQGixxY8cmeJshEXRtUrI75LDMQBBAIK4qzgcqg8KTIAD9m5/BX7m5Y/s67+q0\n” +
“4EIvZEEgmq8/IPuIHkCDix2+e+ZP+VFCfZPA3LUyVSsfVvV0aNf2G/vCsuRLTBOx\n” +
“P1Mqv1/a8xZKHGLwA0L/hloohAOrAgMBAAECgYEApC739Mzwx90GjKfHrCJpv+/0\n” +
“tOaDyyAJfotAn90HgTYHwSpJJAUIAH0wOpW2vFKBetaMZDHFavuURMZe7V/KkbRX\n” +
“Oa4U0RdRBdqXhlLPWV6vXovrzp8QNsaU4k40y1/r12wVREKvd9wVoeUMPmApDlpW\n” +
“yuNS5RTsQZEfTJXQdAkCQQDplPWdJar/rUNUvkHtjSeI1GmstkK4h0tdNt9cZOBG\n” +
“LS7YCL26lxFq4mVq8I7Uw6KMBhBHRxRrpwiXxPvqdprNAkEAw6gIbq837orvbnqg\n” +
“UWYpp1L91e3NuxVtipIJVkKPE4VGKcpoTkAcVyzFDNyfQT76GmK5jvVLw/m6781w\n” +
“uNsIVwJBAL0Uitoh0tFTNQzVUlL0j4swvzZC97GeO4CCWb7WHcJQ8vmH4eW4Qi4u\n” +
“hABUKJrMnrkQc37vZ/VY6hjJKU97oQUCQQCBPtKzKxPrg+O+O0sD+lSxr2T2mGw6\n” +
“lWETFH0OelFBN9ytZoOYjUkrXOueH28kDpHwNB8XjHpMLv+JwVAhDK9pAkEAln6F\n” +
“BHZYpFhiJXdfX5Cme8t9p039TDHmvvJfpRlaftWHIp4YNzyHTAXAm+58nkrIy9AY\n” +
“2snwriQay+UX0RggdQ==\n” +
“—–END PRIVATE KEY—–“;
static String publicKey =”—–BEGIN PUBLIC KEY—–\n” +
“MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyhciJiGBIOr4TXojS0BoscWPH\n” +
“JnibIRF0bVKyO+SwzEAQQCCuKs4HKoPCkyAA/ZufwV+5uWP7Ou/qtOBCL2RBIJqv\n” +
“PyD7iB5Ag4sdvnvmT/lRQn2TwNy1MlUrH1b1dGjX9hv7wrLkS0wTsT9TKr9f2vMW\n” +
“Shxi8ANC/4ZaKIQDqwIDAQAB\n” +
“—–END PUBLIC KEY—–“;

@Test
public void test() throws Exception {
String original = “000000009797976986123456789012345888888888888888888888888888888888888888213hgfjhgfggggguuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuhghg”;
String encryptData = RSAUtils.encryptRSAByPubKey(original, publicKey);
System.out.println(encryptData);

String s = RSAUtils.decryptRSAByPriKey(encryptData, privateKey);
System.out.println(s);

Assert.assertEquals(original, s);
}

}

吾爱博客|AYFRE.COM 版权所有,转载请标明出处
吾爱博客 » JAVA RSA PKCS1 分段加解密

发表评论

吾爱博客|AYFRE.COM