?? rsatools.java
字號:
package com.gmc.algorithms;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.ArrayList;
import javax.crypto.Cipher;
import com.gmc.algorithms.Base64;
import com.gmc.crypto.AsymmetryEncrypt;
/**
* RSA非對稱加密算法的實現類,實現了對字符串、文件、數據流的加密(公鑰加密)、解密(私鑰解密)、數字簽名(私鑰加密)和簽名驗證(公鑰驗證)功能
* 此加密算法操作的數據長度不能大于117位。
* @author wanna
*
*/
public class RSATools implements AsymmetryEncrypt
{
private final static String algorithm = "RSA"; //非對稱加密算法RSA
public static final String SIGNALGORITHM = "SHA1WithRSA"; // 數字簽名算法
private KeyPair rsaKeyPair; //RSA算法的密鑰對
private PublicKey pubKey; //公鑰
private PrivateKey priKey; // 私鑰
private FileInputStream fis;
private FileOutputStream fos;
public RSATools()
{
}
/**
* 解密
* @param cipherText 密文信息
* @param key 解密操作所需的私鑰,如果為null,則不能執行解密操作
* @return 解密后的明文信息
* @throws Exception
*/
public String decrypt(byte[] cipherText, Key key) throws Exception
{
if (cipherText == null || cipherText.length == 0)
{
return null;
}
if (key == null)
{
return null;
}
this.priKey = (PrivateKey) key; //設置解密所用的私鑰
byte[] input = Base64.decode(cipherText); //用Base64對密文解碼
return new String(this.basicDecrypt(input));
}
/**
* 解密
*
* @param cipherText 密文信息
* @param key 解密操作所需的私鑰,如果為null,則不能執行解密操作
* @return 解密后的明文信息 字符串形式
* @throws Exception
*/
public String decrypt(String cipherText, Key key) throws Exception
{
if (cipherText == null)
{
return null;
}
if (key == null)
{
return null;
}
this.priKey = (PrivateKey) key;
byte[] input = Base64.decode(cipherText);
return new String(this.basicDecrypt(input));
}
/**
* 解密 對文件進行解密操作,文件的擴展名必須為.fjm,解密后的明文文件所在路徑與密文相同。
* 例: 密文 :F:\1.txt.fjm
* 明文: F:\1.txt
* @param cipherFile 待解密的文件
* @param key 解密所用的私鑰
* @return 以文件形式存儲的明文信息
* @throws Exception
*/
public File decrypt(File cipherFile, Key key) throws Exception
{
if (cipherFile == null)
{
return null;
}
if (!cipherFile.exists() || cipherFile.isDirectory())
{
return null;
}
if (key == null)
{
return null;
}
this.priKey = (PrivateKey) key;
try
{
String strPath = cipherFile.getPath();
if (!strPath.substring(strPath.length() - 4).toLowerCase().equals(".fjm")) //判斷文件的擴展名是否是fjm,不是停止解密操作
{
return null;
}
fis = new FileInputStream(cipherFile);
byte[] input = this.getByteFromStream(fis); //獲取文件流中的密文數據
byte[] output = this.basicDecrypt(input); //解密
String outFilePath = strPath.substring(strPath.length() - 4);
File fileOut = new File(outFilePath); //存儲明文信息的文件
fos = new FileOutputStream(fileOut);
for (int i = 0; i < output.length; i++)
{
fos.write((int) output[i]);
}
System.out.println("解密成功");
return fileOut;
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
this.closeStream();
}
return null;
}
/**
* 解密 對輸入流中的密文信息進行解密
* @param cipherText 存有密文數據的輸入流
* @param key 解密的私鑰,如果為null,則不能進行解密操作。
* @param plainPath 存儲解密后的明文信息的文件路徑
* @return 指定路徑下,存有明文信息的文件
* @throws Exception
*/
public File decrypt(InputStream cipherText, Key key,String plainPath) throws Exception
{
if(cipherText==null||key==null)
{
return null;
}
if(plainPath==null||plainPath.equals(""))
{
return null;
}
this.priKey= (PrivateKey)key;
byte[] input = this.getByteFromStream(cipherText);
byte[] output = this.basicDecrypt(input);
File outputFile = new File(plainPath);
fos = new FileOutputStream(outputFile);
for(int i=0;i<output.length;i++)
{
fos.write((int)output[i]);
}
System.out.println("解密成功");
return outputFile;
}
/**
* 加密
* @param plainText 明文
* @param key 加密所用的公鑰,如果為null則自動生成一個密鑰對,使用其中的公鑰進行加密
* @return 加密后的密文,字符串形式
* @throws Exception
*/
public String encrypt(byte[] plainText, Key key) throws Exception
{
if (plainText == null || plainText.length == 0)
{
return null;
}
this.setKeyPairWhenEncrypt(key);
return Base64.encode(this.basicEncrypt(plainText));
}
/**
* 加密
* @param plainText 明文
* @param key 加密所用的公鑰,如果為null則自動生成一個密鑰對,使用其中的公鑰進行加密
* @return 加密后的密文,字符串形式
* @throws Exception
*/
public String encrypt(String plainText, Key key) throws Exception
{
if (plainText == null)
{
return null;
}
this.setKeyPairWhenEncrypt(key);
byte[] input = plainText.getBytes();
return Base64.encode(this.basicEncrypt(input));
}
/**
* 加密文件,加密后在file路徑下生成一擴展名為的文件,用于存儲密文信息
* 例: 明文: F:\1.txt
* 密文文件為:F:\1.txt.fjm
* @param file 待加密的文件
* @param key 加密所用的公鑰,如果為null則自動生成一個密鑰對,使用其中的公鑰進行加密
* @return 擴展名為.fjm、存有密文信息的文件
* @throws Exception
*/
public File encrypt(File file, Key key) throws Exception
{
if (file == null)
{
return null;
}
if (!file.exists() || file.isDirectory())
{
return null;
}
try
{
this.setKeyPairWhenEncrypt(key);
fis = new FileInputStream(file);
byte[] input = this.getByteFromStream(fis);
byte[] output = this.basicEncrypt(input);
String cipherFilePath = file.getPath() + ".fjm"; //在 file路徑下創建一擴展名為.fjm的文件
File fileOut = new File(cipherFilePath);
fos = new FileOutputStream(fileOut);
for (int i = 0; i < output.length; i++)
{
fos.write((int) output[i]);
}
System.out.println("加密成功");
return fileOut;
}
catch (Exception e)
{
e.printStackTrace();
throw e;
}
finally
{
this.closeStream();
}
}
/**
* 加密
* @param plainText 存有明文信息的輸入流
* @param key 加密所需公鑰Key如果傳null,則自動生成一個密鑰對,用其中的公鑰進行加密
* @param cipherPath 加密后,存放密文信息的文件路徑
* @return 存有密文件信息的文件
* @throws Exception
*/
public File encrypt(InputStream plainText, Key key,String cipherPath) throws Exception
{
if(plainText==null)
{
return null;
}
if(cipherPath==null||cipherPath.equals(""))
{
return null;
}
try
{
this.setKeyPairWhenEncrypt(key);
byte[] input = this.getByteFromStream(plainText);
byte[] output = this.basicEncrypt(input);
File outputFile = new File(cipherPath);
fos = new FileOutputStream(outputFile);
for(int i = 0;i<output.length;i++)
{
fos.write((int)output[i]);
}
System.out.println("加密成功");
return outputFile;
}catch(Exception e)
{
e.printStackTrace();
throw e;
}
finally
{
this.closeStream();
}
}
/**
* 數字簽名
* @param plainText 明文
* @param key 數字簽名所需私鑰,如果key為null,則自動為其生成一個密鑰對,用其私鑰進行簽名
* @return 字符串形式的簽名信息
* @throws Exception
*/
public String digitalSignature(String plainText, Key key) throws Exception
{
try
{
if (plainText == null)
{
return null;
}
this.setKeyPairWhenSignature(key);
byte[] input = plainText.getBytes();
return Base64.encode(this.basicSignature(input));
}
catch (Exception e)
{
e.printStackTrace();
throw e;
}
}
/**
* 驗證簽名
* @param plainText 明文字符串
* @param signMessage 簽名信息
* @param key 驗證簽名所需的公鑰,為null則不能進行驗證
* @return 驗證結果
* true 簽名正確
* false簽名錯誤
* @throws Exception
*/
public boolean validateSignature(String plainText, String signMessage, Key key) throws Exception
{
try
{
if (plainText == null || signMessage == null)
{
return false;
}
if (key == null)
{
return false;
}
else
{
this.pubKey = (PublicKey) key;
}
byte[] plain = plainText.getBytes();
byte[] input = Base64.decode(signMessage);
return this.basicValidateSign(plain, input);
}
catch (Exception e)
{
e.printStackTrace();
throw e;
}
}
/**
* 對文件進行數字簽名,存有簽名信息的文件擴展名為.sig,與file在相同目錄下
* 例: file : F:\1.txt
* 簽名信息文件: F:\1.txt.sig
* @param file 待簽名的文件
* @param key 數字簽名所需公鑰,傳入null,則自動生成一組密鑰對,用其私鑰進行簽名操作
* @return 存有簽名信息的文件
* @throws Exception
*/
public File digitalSignature(File file, Key key) throws Exception
{
if (file == null)
{
return null;
}
if (!file.exists() || file.isDirectory())
{
return null;
}
try
{
this.setKeyPairWhenSignature(key);
fis = new FileInputStream(file);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -