```java
package shiyan;
/**
*下面我們開始導包 , 土話 就是 把 那個文件夾下的 什麼東西 拿來 ,我要用,
*java是重量級的包,javax是輕量級的包!!
* */
import org.apache.commons.codec.binary.Base64;//Commons項目中用來處理常用的編碼方法的工具類包,例如DES、SHA1、MD5、Base64, 及 hex, metaphone, soundex 等編碼演算。
import org.apache.commons.io.IOUtils;//apache.commons模塊已經封裝了快速讀取文件內容的工具類IOUtils,在項目中可以直接使用,非常方便!
import java.util.*; //Java的實用工具類庫java.util包。在這個包中,Java提供了一些實用的方法和數據結構。
import javax.crypto.Cipher;//提供加解密功能 import java.io.ByteArrayOutputStream;//ByteArrayOutputStream是字節數組輸出流,在內存中創建了一個字節數組,所有發送到輸出流的數據都會保存到該字節數組的緩衝區中.
import java.security.*;//Java加密框架,裏面有不同的類,每個類定義了一種服務!!比如有:MessageDigest(生成摘要)、Signature(簽名)、KeyPairGenerator(生成公私鑰對)、AlgorithmParameters(管理算法的參數)、、
import java.security.interfaces.RSAPrivateKey;//提供的接口用於生成私鑰
import java.security.interfaces.RSAPublicKey;//提供的接口用於生成如公鑰
import java.security.spec.*;//
import java.security.spec.PKCS8EncodedKeySpec;//PKCS8格式的祕鑰(適用於java)。
import java.security.spec.X509EncodedKeySpec;//X509的標準進行加密
import java.util.HashMap;
import java.util.Map;
import java.io.*;//提供一個合理的路徑,使得編譯器可以找到某個類(這裏是FileReader類)。
/**圖形界
* 面化的
* 依賴
* 導入包*/
import java.awt.*;//包含用於創建用戶界面和繪製圖形圖像的所有類
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.awt.event.*;
public class RSA {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
private static String securitymessage = "F:\\test\\src\\shiyan\\securitymessage";//指定程序執行結果保存的文件路徑,保存密文
private static String securitykey = "F:\\test\\src\\shiyan\\securitykey";//保存密鑰
private static String message = "F:\\test\\src\\shiyan\\message";//提取輸入的明文
public static Map<String, String> createKeys(int keySize) {
//爲RSA算法創建一個KeyPairGenerator對象
KeyPairGenerator kpg;
try
{
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
//初始化KeyPairGenerator對象,密鑰長度
kpg.initialize(keySize);
//生成密匙對
KeyPair keyPair = kpg.generateKeyPair();
//得到公鑰
Key publicKey = keyPair.getPublic();
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
//得到私鑰
Key privateKey = keyPair.getPrivate();
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
return keyPairMap;
}
/**
* 得到公鑰
* @param publicKey 密鑰字符串(經過base64編碼)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通過X509編碼的Key指令獲得公鑰對象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
/**
* 得到私鑰
* @param privateKey 密鑰字符串(經過base64編碼)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通過PKCS
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* 公鑰加密
*
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]時遇到異常", e);
}
}
/**
* 私鑰解密
*
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
}
}
/**
* 私鑰加密
*/
public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]時遇到異常", e);
}
}
/**
* 公鑰解密
*/
public static String publicDecrypt(String data, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
}
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock = 0;
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
} catch (Exception e) {
throw new RuntimeException("加解密閥值爲[" + maxBlock + "]的數據時發生異常", e);
}
byte[] resultDatas = out.toByteArray();
// IOUtils.closeQuietly(out);
return resultDatas;
}
public static void main(String[] args) throws Exception {
// Runtime.getRuntime().exec("cmd.exe /c start "+"C:\\Users\\banxiao\\Desktop\\大三上-各專業報告\\java程序設計實驗\\雜.txt");//將txt文件打開
System.out.println("請選擇您要生成的公私鑰位數:有512、1024、2048、4096位四種");
Scanner input= new Scanner(System.in);
int str= input.nextInt();
Map<String, String> keyMap = RSAUtils.createKeys(str);
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
System.out.println("下面是選擇"+str+"位生成的公鑰和私鑰");
System.out.println("公鑰加密——私鑰解密;私鑰簽名——公鑰驗證");
JFrame frame = new JFrame("一個關於RSA的加密解密窗口");
// frame.setSize(400,400);//設置窗口大小
// Button名稱
JButton button0 = new JButton("瀏覽");
JButton button1 = new JButton("加密");
JButton button2 = new JButton("解密");
JButton button3 = new JButton("簽名");
JButton button4 = new JButton("驗證");
// JTextField名稱,定義文本框的大小
final JTextField content = new JTextField();
// content.setName("content");
final JTextField pass = new JTextField();
// content.setName("pass");
final JTextField dpass = new JTextField();
final JTextField sign = new JTextField();
// content.setName("sign");
final JTextField prove = new JTextField();
// JLabel
JLabel view = new JLabel("瀏覽", JLabel.CENTER);
view.setFont(new java.awt.Font("Dialog", 1, 15));//Dialog代表字體,1代表粗0代表細,15代表字號
view.setOpaque(true); //設置控件是否透明的。true表示不透明,false表示透明。
view.setBackground(Color.white);
view.setForeground(Color.black);
// 畫布佈局
JPanel contentPane = new JPanel();//實例化一個面板,把其它組件添加到Jpanel中;
// contentPane.setBackground(Color.white);
//contentPane.setSize(1000,1000);
contentPane.add(button0);
contentPane.add(button1);
contentPane.add(button2);
contentPane.add(button3);
contentPane.add(button4);
contentPane.add(content);
contentPane.add(pass);
contentPane.add(dpass);
contentPane.add(sign);
contentPane.add(prove);
contentPane.add(view);
frame.setContentPane(contentPane);
contentPane.setLayout(null);//設置窗體佈局
// 按鈕大小設置(x,y,長度,寬度)
content.setBounds(131, 4, 200, 40);
button0.setBounds(50, 4, 80, 40);
pass.setBounds(131, 50, 200, 40);
button1.setBounds(50, 50, 80, 40);
dpass.setBounds(131, 100, 200, 40);
button2.setBounds(50, 100, 80, 40);
sign.setBounds(131, 150, 200, 40);
button3.setBounds(50, 150, 80, 40);
prove.setBounds(131, 200, 200, 40);
button4.setBounds(50, 200, 80, 40);
frame.setSize(500, 500);//設置窗口大小
frame.setVisible(true);//把窗口設置爲可見
//瀏覽,選擇本地文件夾內容進行加密。
button0.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
JFileChooser jfc=new JFileChooser();//用於加載桌面或者某硬盤的文件,進行加密
if(jfc.showOpenDialog(null)==JFileChooser.APPROVE_OPTION)//這裏showDialog,彈出具有自定義 approve 按鈕的自定義文件選擇器對話框。該文件選擇器被彈下時的返回狀態:JFileChooser.CANCEL_OPTIONJFileChooser.APPROVE_OPTIONJFileChooser.ERROR_OPTION 。
{
String file=jfc.getSelectedFile().getAbsolutePath();
// MyFileReader rf;
try {
int c=-1;
byte[] b=new byte[10004];
FileInputStream fis=new FileInputStream(file);
//rf = new MyFileReader(file);
while((c=fis.read(b))!=-1) {
String s= new String(b,0,c);
System.out.println(s);
content.setText(s);
}
/*Scanner input=new Scanner(file);
while(input.hasNext()){
content.setText(input.nextLine());
// System.out.println(input.nextLine());
}*/
input.close();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/*
while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
{
String encodedData = String.valueOf(c);
// System.out.print(encodedData);
content.setText(encodedData);
}
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
input.close();
while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
{
String encodedData = String.valueOf(c);
// System.out.print(encodedData);
content.setText(encodedData);
}
/*}
Scanner input=new Scanner(file);
while(input.hasNext()){
content.setText(input.nextLine());
// System.out.println(input.nextLine());
}
input.close();
}
else
System.out.println("No file is selected!");
}
MyFileReader rf = new MyFileReader();
FileWriter fw1 = new FileWriter(file);
int c;
while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
{
String encodedData = String.valueOf(c);
fw1.write(encodedData);
fw1.flush();
}
while(fw1.hasNext()){
String str1 = input.nextLine().toString();
try {
pass.setText(encrypt(str1));
}catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
input.close();
}
else
System.out.println("No file is selected!");
*/
}
}
}
);
//加密的按鈕及內容的設置
button1.addActionListener(
new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
String str1 = content.getText().toString();
try {
pass.setText(RSAUtils.publicEncrypt(str1, RSAUtils.getPublicKey(publicKey)));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
);
//解密的按鈕及內容的設置
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String str2 = pass.getText().toString();
try {
dpass.setText(RSAUtils.privateDecrypt(str2, RSAUtils.getPrivateKey(privateKey)));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
//簽名的按鈕及內容設置
button3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
String str1 = content.getText().toString();
try {
sign.setText(RSAUtils.privateEncrypt(str1, RSAUtils.getPrivateKey(privateKey)));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
//驗證的按鈕一內容的設置
button4.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String str2 = sign.getText().toString();
String str1 = content.getText().toString();
System.out.println(str1);
try {
String str=RSAUtils.publicDecrypt(str2, RSAUtils.getPublicKey(publicKey));
if(str.equals(str1)) prove.setText("驗證失敗");
prove.setText("驗證成功");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //釋放內存
/*
//子類對象的實例化
MyFileReader rf = new MyFileReader(message);
FileWriter fw = new FileWriter(securitymessage);
FileWriter fw1 = new FileWriter(securitykey);
int c;
while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
{
String encodedData = RSAUtils.publicEncrypt(String.valueOf(c), RSAUtils.getPublicKey(publicKey));
fw.write(encodedData);
fw.flush();
}
// System.out.println("\r明文大小:\r\n" + str.getBytes().length+"B");
//讀完後關閉打開的filte文檔。\
fw1.write("公鑰:\n "+publicKey+"\n"+"私鑰:\n" + privateKey);
fw1.flush();
rf.close();
fw.close();
fw1.close();
}
JFrame frame = new JFrame("RSA加密解密");
// Button名稱
JButton button1 = new JButton("加密");
JButton button2 = new JButton("解密");
// JTextField名稱
final JTextField content = new JTextField();
content.setName("content");
final JTextField pass = new JTextField();
final JTextField dpass = new JTextField();
// JLabel
JLabel view = new JLabel("明文", JLabel.CENTER);
view.setFont(new java.awt.Font("明文", 1, 15));//1代表粗細,15代表粗細
view.setOpaque(true);
view.setBackground(Color.GREEN);
view.setForeground(Color.BLACK);
// 畫布佈局
JPanel contentPane = new JPanel();
contentPane.add(button1);
contentPane.add(button2);
contentPane.add(content);
contentPane.add(pass);
contentPane.add(dpass);
contentPane.add(view);
frame.setContentPane(contentPane);
contentPane.setLayout(null);
// 大小設置
view.setBounds(250, 0, 80, 30);
content.setBounds(50, 0, 200, 30);
pass.setBounds(50, 50, 200, 30);
button1.setBounds(250, 50, 80, 30);
dpass.setBounds(50, 100, 200, 30);
button2.setBounds(250, 100, 80, 30);
frame.setSize(400, 300);
frame.setVisible(true);
button1.addActionListener(
new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
String str1 = content.getText().toString();
try {
pass.setText(publicEncrypt(str1,publicKey));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
);
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String str2 = content.getText().toString();
try {
dpass.setText(str2);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
}
/* String str = "青青子衿\n" +
"悠悠我心\n" +
"但爲君故\n" +
"沉吟至今\n" +
"呦呦鹿鳴\n" +
"食野之萍\n" +
"我要拉屎"; */
/*
String encodedData = RSAUtils.publicEncrypt(str, RSAUtils.getPublicKey(publicKey));
System.out.println("密文:\r\n" + encodedData);
String decodedData = RSAUtils.privateDecrypt(encodedData, RSAUtils.getPrivateKey(privateKey));
System.out.println("解密後文字: \r\n" + decodedData);
System.out.println("私鑰簽名——公鑰驗證\n");
String str1= input.nextLine();
System.out.println("\r明文:\r\n" + str1);
System.out.println("\r明文大小:\r\n" + str1.getBytes().length+"B");
String encodedData1 = RSAUtils.privateEncrypt(str1, RSAUtils.getPrivateKey(publicKey));
System.out.println("密文:\r\n" + encodedData1);
String decodedData1 = RSAUtils.publicDecrypt(encodedData1, RSAUtils.getPublicKey(privateKey));
System.out.println("解密後文字: \r\n" + decodedData1);
}
*/
}
}