```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);
}
*/
}
}