一.实验要求
1、实验时,除必须完成的 DES 和 RSA 实验外,每位学生还需从剩余的实验项目任选一个项目完成。
2、在实验报告中要详细说明实验的步骤,包括程序说明。实验过程及结果截图
二.实验内容
DES加解密实验
DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977 年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。DES 加解密工具代码已给出,使用如下方式进行字符串的加解密操作:
使用如下方式进行文件的加解密操作:
对实验结果进行截图,尝试对不同类型的文件,如视频、音频等进行加解密处理。
AES加解密实验
AES 全称为 Advanced Encryption Standard,是美国联邦政府采用的一种区块加密标准,用来替代原先的 DES。AES 加解密工具代码已给出,使用如下方式进行字符串加解密操作:
注意,这里的密钥必须为 16 字节(128 位)。使用如下方式对文件进行加解密:
对运行结果进行截图,对实验结果进行截图,尝试对不同类型的文件,如视频、音频等进行加解密处理。
RSA加解密实验
RSA 加密算法,是世界上第一个非对称加密算法,也是数论的第一个实际应用。它的算法如下:
1.找两个非常大的质数 p 和 q(通常 p 和 q 都有 155 十进制位或都有 512 十进制位)并计算 n=pq,k=(p-1)(q-1)。
2.将明文编码成整数 M,保证 M 不小于 0 但是小于 n。
3.任取一个整数 e,保证 e 和 k 互质,而且 e 不小于 0 但是小于 k。加密钥匙(称作公钥)是(e, n)。
4.找到一个整数 d,使得 ed 除以 k 的余数是 1(只要 e 和 n 满足上面条件,d(肯定存在)。解密钥匙(称作密钥)是(d, n)。
加密过程: 加密后的编码 C 等于 M 的 e 次方除以 n 所得的余数。
解密过程: 解密后的编码 N 等于 C 的 d 次方除以 n 所得的余数。
只要 e、d 和 n 满足上面给定的条件。M 等于 N。
通过如下方式对字符串进行加解密:
对实验结果进行截图,比较 RSA 加解密操作与前文中对称加密算法加解密操作的不同。
三.实验步骤
DES加解密实验
AES加解密实验
RSA加解密实验
四.源代码
package informationsafety;
import java.io.*;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import java.util.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class experimentone{
public static void main(String[] args){
String password = "aaaaaaaaaaaaaaaa";
String str = "jhxfjdhfjxhcj,fdgh.ieuri/djfdh.";
String file = "D:/testone.txt";//需要预先创造好文件
String destFile = "D:/testtwo.txt";
String endFile = "D:/testthr.txt";
System.out.println("选择模式:(1.DES加密字符串,2.DES加密文件,3.AES加密字符串,4.AES加密文件,5.RSA加密字符串)");
Scanner sc = new Scanner(System.in);
String scs = sc.next();
sc.close();
int scd = Integer.parseInt(scs);
switch(scd) {
case 1:
System.out.println("加密前的字符串:"+str);
try {
byte[] res = DES.enpt(str.getBytes(), password);
DES.dept(res, password);
}catch (Exception e) {
e.printStackTrace();
}
break;
case 2:
try {
DES.enptfile(password, file, destFile);
DES.deptfile(password, destFile, endFile);
}catch (Exception e) {
e.printStackTrace();
}
break;
case 3:
System.out.println("加密前的字符串:"+str);
try {
byte[] tes = AES.enpt(str.getBytes(),password);
AES.dept(tes,password);
} catch (Exception e) {
e.printStackTrace();
}
break;
case 4:
try {
AES.enptfile(password, file, destFile);
AES.deptfile(password, destFile, endFile);
}catch (Exception e) {
e.printStackTrace();
}
break;
case 5:
try {
RSA.achieveRSA(str);
}catch (Exception e) {
e.printStackTrace();
}
break;
default:System.out.println("Error");
}
}
}
class DES{
public static byte[] enpt(byte[] datasource, String password) {
try{
SecureRandom ran = new SecureRandom();//生成随机数
DESKeySpec dKey = new DESKeySpec(password.getBytes());//组成DES的密钥
SecretKeyFactory kF = SecretKeyFactory.getInstance("DES");//建立密钥工厂
SecretKey skey = kF.generateSecret(dKey);//生成一个密钥
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, skey, ran);
byte[] res = cipher.doFinal(datasource);
String re = new String(res);
System.out.println("DES加密后的结果:"+re);
return res;
}catch(Throwable e){
e.printStackTrace();
}
return null;
}
public static void dept(byte[] src, String password) {
try{
SecureRandom ran = new SecureRandom();
DESKeySpec dKey = new DESKeySpec(password.getBytes());
SecretKeyFactory kF = SecretKeyFactory.getInstance("DES");
SecretKey skey = kF.generateSecret(dKey);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, skey, ran);
byte[] Res = cipher.doFinal(src);
System.out.println("DES解密后的结果:"+new String(Res));
}catch(Throwable e) {
e.printStackTrace();
}
}
public static void enptfile(String password,String file,String destFile) {
try {
SecureRandom ran = new SecureRandom();
DESKeySpec dKey = new DESKeySpec(password.getBytes());
SecretKeyFactory kF = SecretKeyFactory.getInstance("DES");
SecretKey skey = kF.generateSecret(dKey);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, skey, ran);
byte[] buffer = new byte[1024];
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(destFile);
CipherInputStream cin = new CipherInputStream(in,cipher);
int r = 0;
while ((r = cin.read(buffer))!=-1) {
out.write(buffer, 0, r);
}
cin.close();
in.close();
out.close();
System.out.println("加密结束。");
}catch(Throwable e) {
e.printStackTrace();
}
}
public static void deptfile(String password,String file,String destFile) {
try {
SecureRandom ran = new SecureRandom();
DESKeySpec dKey = new DESKeySpec(password.getBytes());
SecretKeyFactory kF = SecretKeyFactory.getInstance("DES");
SecretKey skey = kF.generateSecret(dKey);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, skey, ran);
byte[] buffer = new byte[1024];
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(destFile);
CipherOutputStream cot = new CipherOutputStream(out,cipher);
int r = 0;
while ((r = in.read(buffer))!=-1) {
cot.write(buffer, 0, r);
}
cot.close();
in.close();
out.close();
System.out.println("解密结束。");
}catch(Throwable e) {
e.printStackTrace();
}
}
}
class AES{
public static byte[] enpt(byte[] datasource, String password) {
try{
SecureRandom ran = SecureRandom.getInstance("SHA1PRNG");
ran.setSeed(password.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
kgen.init(128,ran);// 利用用户密码作为随机数初始化出
SecretKey sK = kgen.generateKey();// 根据用户密码,生成一个密钥
byte[] enCodeF = sK.getEncoded();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回
SecretKeySpec key = new SecretKeySpec(enCodeF, "AES");// 转换为AES专用密钥
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器
byte[] tes = cipher.doFinal(datasource);
String te = new String(tes);
System.out.println("AES加密后的结果:"+te);
return tes;
}catch(Throwable e){
e.printStackTrace();
}
return null;
}
public static void dept(byte[] src, String password) {
try{
SecureRandom ran = SecureRandom.getInstance("SHA1PRNG");
ran.setSeed(password.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128,ran);
SecretKey sK = kgen.generateKey();
byte[] enCodeF = sK.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeF, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] Tes = cipher.doFinal(src);
System.out.println("AES解密后的结果:"+new String(Tes));
}catch(Throwable e) {
e.printStackTrace();
}
}
public static void enptfile(String password,String file,String destFile) {
try {
SecureRandom ran = SecureRandom.getInstance("SHA1PRNG");
ran.setSeed(password.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128,ran);
SecretKey sK = kgen.generateKey();
byte[] enCodeF = sK.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeF, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] buffer = new byte[1024];
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(destFile);
CipherInputStream cin = new CipherInputStream(in,cipher);
int r = 0;
while ((r = cin.read(buffer))!=-1) {
out.write(buffer, 0, r);
}
cin.close();
in.close();
out.close();
System.out.println("加密结束。");
}catch(Throwable e) {
e.printStackTrace();
}
}
public static void deptfile(String password,String file,String destFile) {
try {
SecureRandom ran = SecureRandom.getInstance("SHA1PRNG");
ran.setSeed(password.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128,ran);
SecretKey sK = kgen.generateKey();
byte[] enCodeF = sK.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeF, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] buffer = new byte[1024];
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(destFile);
CipherOutputStream cot = new CipherOutputStream(out,cipher);
int r = 0;
while ((r = in.read(buffer))!=-1) {
cot.write(buffer, 0, r);
}
cot.close();
in.close();
out.close();
System.out.println("解密结束。");
}catch(Throwable e) {
e.printStackTrace();
}
}
}
class RSA{
private static Map<Integer, String> keyMap = new HashMap<Integer, String>();
public static void getkey() {
try {
SecureRandom ran = new SecureRandom();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024,ran);
KeyPair kp = kpg.generateKeyPair();
RSAPrivateKey privatekey = (RSAPrivateKey) kp.getPrivate();//得到私钥
RSAPublicKey publickey = (RSAPublicKey) kp.getPublic();//得到公钥
String publicKeyString = new String(Base64.getEncoder().encode(publickey.getEncoded()));//得到私钥字符串
String privateKeyString = new String(Base64.getEncoder().encode((privatekey.getEncoded())));//将公钥和私钥保存到Map
keyMap.put(0,publicKeyString); //0表示公钥
keyMap.put(1,privateKeyString); //1表示私钥
}catch(Throwable e) {
e.printStackTrace();
}
}
public static String encrypt(String str, String publicKey) throws Exception{
byte[] decoded = Base64.getDecoder().decode(publicKey);
RSAPublicKey pubkey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubkey);
String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
public static String decrypt(String str, String privateKey) throws Exception{
byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8"));
byte[] decoded = Base64.getDecoder().decode(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
public static void achieveRSA(String str) throws Exception{
RSA.getkey();
String stre = encrypt(str,keyMap.get(0));
System.out.println("加密前的字符串:"+str + "\n加密后的字符串为:" + stre);
String strd = decrypt(stre,keyMap.get(1));
System.out.println("还原后的字符串为:" + strd);
}
}