RSA非对称加密算法,针对大型文本文件进行加解密,需要分段加密和解密
private static String algorithm = "RSA"; //$NON-NLS-1$
private static String data = readString("需要加密文件路径");
private static Map<Integer, String> keyMap = new HashMap<Integer, String>();
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, IOException {
genKeyPair();
String test = testEncrypt(keyMap.get(1),data);
String testDecrypt = testDecrypt(keyMap.get(0), test);
FileOutputStream os = new FileOutputStream("加密后文件输出路径");
os.write(test.getBytes());
System.out.println(testDecrypt);
}
public static void genKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
String publicKeyString = new String(org.apache.commons.codec.binary.Base64.encodeBase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(org.apache.commons.codec.binary.Base64.encodeBase64((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
keyMap.put(0,publicKeyString); //0表示公钥
keyMap.put(1,privateKeyString); //1表示私钥
}
private static String readString(String filePath)
{
int len=0;
StringBuffer str=new StringBuffer("");
File file=new File(filePath);
try {
FileInputStream is=new FileInputStream(file);
InputStreamReader isr= new InputStreamReader(is);
BufferedReader in= new BufferedReader(isr);
String line=null;
while( (line=in.readLine())!=null )
{
if(len != 0) // 处理换行符的问题
{
str.append("\r\n"+line);
}
else
{
str.append(line);
}
len++;
}
in.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str.toString();
}
public static String testEncrypt(String key,String data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, IOException{
byte[] decode = Base64.getDecoder().decode(key);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
KeyFactory kf = KeyFactory.getInstance(algorithm);
PrivateKey generatePrivate = kf.generatePrivate(pkcs8EncodedKeySpec);
Cipher ci = Cipher.getInstance(algorithm);
ci.init(Cipher.ENCRYPT_MODE, generatePrivate);
byte[] bytes = data.getBytes();
int inputLen = bytes.length;
int offLen = 0;
int i = 0;
ByteArrayOutputStream bops = new ByteArrayOutputStream();
while(inputLen - offLen > 0){
byte [] cache;
if(inputLen - offLen > 117){
cache = ci.doFinal(bytes, offLen,117);
}else{
cache = ci.doFinal(bytes, offLen,inputLen - offLen);
}
bops.write(cache);
i++;
offLen = 117 * i;
}
bops.close();
byte[] encryptedData = bops.toByteArray();
String encodeToString = Base64.getEncoder().encodeToString(encryptedData);
return encodeToString;
}
public static String testDecrypt(String key,String data) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, IOException{
byte[] decode = Base64.getDecoder().decode(key);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
KeyFactory kf = KeyFactory.getInstance(algorithm);
PublicKey generatePublic = kf.generatePublic(x509EncodedKeySpec);
Cipher ci = Cipher.getInstance(algorithm);
ci.init(Cipher.DECRYPT_MODE,generatePublic);
byte[] bytes = Base64.getDecoder().decode(data);
int inputLen = bytes.length;
int offLen = 0;
int i = 0;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while(inputLen - offLen > 0){
byte[] cache;
if(inputLen - offLen > 128){
cache = ci.doFinal(bytes,offLen,128);
}else{
cache = ci.doFinal(bytes,offLen,inputLen - offLen);
}
byteArrayOutputStream.write(cache);
i++;
offLen = 128 * i;
}
byteArrayOutputStream.close();
byte[] byteArray = byteArrayOutputStream.toByteArray();
return new String(byteArray);
}