背景
之前我一直不明白,比如A、B双方加密通信的时候,为什么A要使用B的公钥来加密,为A什么不使用A的私钥加密,然后B用A的公钥解密不就可以了吗?
其实,A的私钥主要是A用来签名的,签名顾名思义是表明这个东西是A发送的,而不是别人发过来的。为什么A用自己的私钥签名就说明这个东西就是A发过来的呢?因为用B用A的公钥解签的时候,得到了原文的数据摘要,然后B根据得到的明文信息然后使用Hash函数重新得到数据摘要,两个数据摘要一对比,如果一致,那么就是A发过来的,表明了即使A发过来的且原文信息没有被改动过。
具体流程图下图所示:
目标
使用Java语言,实现RSA数据摘要+数据签名。
代码
程序入口文件:MainEntrance
package RSA;
/**
* @author yourname
* @date 2018年10月16日 下午5:12:18
*
*/
public class MainEntrance {
public static void main(String[] args) {
try {
new Test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
窗口界面以及事件处理文件:Test
package RSA;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Map;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
/**
* @author yourname
* @date 2018年10月16日 下午6:45:43
*
*/
public class Test extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
String a2="";
int pd;
Map<String, Object> keyMap;
String textPlainMD5 = "";
String byte2Base64 = "";
byte[] publicDecrypt = null;
public Test() throws Exception
{
//使用Map存放初始化的公钥和私钥
keyMap = CreateSecrteKey.initKey();
//创建容器和控件
Container c1 = getContentPane();
getContentPane().setLayout(null);//布局
getContentPane().setBackground(Color.LIGHT_GRAY);
JLabel jl1 =new JLabel("请输入明文:");
JLabel jl2 =new JLabel("选择方式:");
JLabel jl3 =new JLabel("结果:");
JTextField jt1 = new JTextField(10);
JLabel jt3 = new JLabel("");
//设置jt3的字体
jt3.setFont(new Font("宋体",Font.BOLD, 8));
JButton jb = new JButton("开始");
jb.setBorderPainted(true);//设置按钮显示边界
JButton jb1 = new JButton("反解");
jb1.setBorderPainted(true);//设置按钮显示边界
JRadioButton jr1 = new JRadioButton("提取数据摘要(MD5)");//单选按钮
JRadioButton jr2 = new JRadioButton("RSA数据签名");
ButtonGroup group = new ButtonGroup();//没有这句,你的单选按钮就不叫单选按钮,可以自己去掉试试
group.add(jr1);
group.add(jr2);
//控件加入到容器
c1.add(jl1);
c1.add(jt1);
c1.add(jl2);
c1.add(jr1);
c1.add(jr2);
c1.add(jl3);
c1.add(jt3);
c1.add(jb);
c1.add(jb1);
setSize(400, 200);
setVisible(true);
setTitle("RSA签名算法");
//设置各个控件的绝对位置
jl1.setBounds(5,5,80,20);
jt1.setBounds(85, 5, 150, 20);
jl2.setBounds(5, 25, 80, 20);
jr1.setBounds(85, 25, 160, 25);
jr2.setBounds(85,65,140,25);