一、实习目的
1.理解公钥密码算法,熟悉常用密码算法:RSA、椭圆曲线密码体制;
2.以RSA加密算法为例,掌握公钥密码算法加解密过程的实现。
二、实现要求
1.实习前认真预习第6章的有关内容;
2.熟悉java中java.security.*和java.crypto.* 中相关类。
三、实习内容
1.[阶梯任务]:实习任务按照难度渐次给出,阶梯(1)为必须完成的基础任务,请结合自己的实际选择后续阶梯任务
(1) 以本地两个目录模拟两个用户,实现基本RSA加密通讯,引入的包具体到类;
(2) 对于RSA加密实现图形界面,用户可以输入明文和密钥,在文本框中显示对应密文;
(3) 实现用户对文件的操作,用户可以通过指定路径文件和密钥,加密结果存储在指定文件中;
(4) 采用SOCKET,建立安全通信过程;
(5) 将方案移植到某个web应用中。
2.[实现提示]
(1) 可以利用java中的KeypairGenerator类创建公钥密钥对,工厂类KeypairGenerator的静态方法getInstance()可以获得KeypairGenerator类型对象。
(2) 方法getInstance()的参数为字符串类型,指定加密算法的名称如:RSA。
(3) 利用工厂类Cipher的对象创建密码器。同样的,getInstance()的参数为字符串类型,指定加密算法的名称。
(4) JSDK1.2中只是实现了RSA密钥创建,没有实现RSA算法,因此需要安装其他加密软件提供者的软件包,才能直接使用Cipher类执行加解密。
(5) RSA算法是使用整数进行加密运算的,RSA的公钥中包含两个信息:公钥对应的整数e和用于取模的整数n。对于明文m计算密文的公式是me mod n。java中的BigInteger类中定义的modPow()方法可以计算me mod n。
(6) RSA的私钥中包含两个信息:私钥对应的整数d和用于取模的整数n。计算明文的公式是:Ce mod n。
四、实验设计
1、基本思路
RSA算法实现总共需要定义三个类,首先,定义SKey_RSA类,这个类主要是生成公钥密钥对。利用java中的KeyPairGenerator类创建公钥密钥对,工厂类KeyPairGenerator的静态方法getInstance()可以获得KeyPairGenerator类型对象。指定密钥长度,生成密钥对,并将其公钥和私钥分别输出到文件
Skey_RSA_pub.dat和Skey_RSA_priv.dat中。其次,定义Enc_RSA类,进行加密,在主函数中,先输入一个字符串明文然后读取文件Skey_RSA_pub.dat获取公钥,然后获取公钥参数(公钥对应的整数e和用于取模的整数n),将加密后的缓存写入到文件Enc_RSA.dat中。最后是定义Dec_RSA类,这是基于RSA的解密。首先先获取文件Enc_RSA.dat,依次读取文件内容,在读取存入Skey_RSA_priv.dat文件中的私钥,然后获取私钥参数(私钥对应的整数e和用于取模的整数n),将解密后的内容输出。
2、类图设计
3、核心方法流程图设计
五、实验结果测试
1.加密
2.解密
3.加密图形界面
4.解密图形界面
代码
package work3;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateKey;
public class Dec_RSA {
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
BufferedReader in=new BufferedReader(new InputStreamReader(new FileInputStream("Enc_RSA.dat")));
String ctext=in.readLine();
BigInteger c=new BigInteger(ctext);
FileInputStream f=new FileInputStream("Skey_RSA_priv.dat");
@SuppressWarnings("resource")
ObjectInputStream b=new ObjectInputStream(f);
RSAPrivateKey prk=(RSAPrivateKey)b.readObject();
BigInteger d=prk.getPrivateExponent();
BigInteger n=prk.getModulus();
System.out.println("d="+d);
System.out.println("n="+n);
BigInteger m=c.modPow(d, n);
System.out.println("m="+m);
byte[] mt=m.toByteArray();
System.out.println("PlainTwxt is");
for(int i=0;i<mt.length;i++){
System.out.print((char)mt[i]);
}
}
}
package work3;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
public class Enc_RSA {
public static void main(String[] args) throws Exception {
String s="Hello World!";
FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
@SuppressWarnings("resource")
ObjectInputStream b=new ObjectInputStream(f);
RSAPublicKey pbk=(RSAPublicKey)b.readObject();
BigInteger e=pbk.getPublicExponent();
BigInteger n=pbk.getModulus();
System.out.println("e="+e);
System.out.println("n="+n);
byte ptext[]=s.getBytes("UTF-8");
BigInteger m=new BigInteger(ptext);
BigInteger c=m.modPow(e, n);
System.out.println("c="+c);
String cs=c.toString();
BufferedWriter out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Enc_RSA.dat")));
out.write(cs,0,cs.length());
out.close();
}
}
package work3;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class RSA_Encrypt {
/** 指定加密算法为DESede */
private static String ALGORITHM = "RSA";
/** 指定key的大小 */
private static int KEYSIZE = 1024;
/** 指定公钥存放文件 */
private static String PUBLIC_KEY_FILE = "PublicKey";
/** 指定私钥存放文件 */
private static String PRIVATE_KEY_FILE = "PrivateKey";
/**
* 生成密钥对
*/
private static void generateKeyPair() throws Exception {
/** RSA算法要求有一个可信任的随机数源 */
SecureRandom sr = new SecureRandom();
/** 为RSA算法创建一个KeyPairGenerator对象 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
/** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
kpg.initialize(KEYSIZE, sr);
/** 生成密匙对 */
KeyPair kp = kpg.generateKeyPair();
/** 得到公钥 */
Key publicKey = kp.getPublic();
/** 得到私钥 */
Key privateKey = kp.getPrivate();
/** 用对象流将生成的密钥写入文件 */
ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
oos1.writeObject(publicKey);
oos2.writeObject(privateKey);
/** 清空缓存,关闭文件输出流 */
oos1.close();
oos2.close();
}
/**
* 加密方法 source: 源数据
*/
public static String encrypt(String source) throws Exception {
generateKeyPair();
/** 将文件中的公钥对象读出 */
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
Key key = (Key) ois.readObject();
ois.close();
/** 得到Cipher对象来实现对源数据的RSA加密 */
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] b = source.getBytes();
/** 执行加密操作 */
byte[] b1 = cipher.doFinal(b);
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(b1);
}
/**
* 解密算法 cryptograph:密文
*/
public static String decrypt(String cryptograph) throws Exception {
/** 将文件中的私钥对象读出 */
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
Key key = (Key) ois.readObject();
/** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
BASE64Decoder decoder = new BASE64Decoder();
byte[] b1 = decoder.decodeBuffer(cryptograph);
/** 执行解密操作 */
byte[] b = cipher.doFinal(b1);
return new String(b);
}
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame("RSA加密解密");
// Button名称
JButton button1 = new JButton("加密");
JButton button2 = new JButton("解密");
// JTextField名称
final JTextField content = new JTextField();
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));
view.setOpaque(true);
view.setBackground(Color.WHITE);
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) {
String str1 = content.getText().toString();
try {
pass.setText(encrypt(str1));
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String str2 = content.getText().toString();
try {
dpass.setText(str2);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
}
}
package work3;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
public class SKey_RSA {
public static void main(String[] args) throws Exception {
KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp=kpg.genKeyPair();
PublicKey pbkey=kp.getPublic();
PrivateKey prkey=kp.getPrivate();
FileOutputStream f1=new FileOutputStream("Skey_RSA_pub.dat");
@SuppressWarnings("resource")
ObjectOutputStream b1=new ObjectOutputStream(f1);
b1.writeObject(pbkey);
FileOutputStream f2=new FileOutputStream("Skey_RSA_priv.dat");
@SuppressWarnings("resource")
ObjectOutputStream b2=new ObjectOutputStream(f2);
b2.writeObject(prkey);
}
}