数字信封加密技术(RSA和DES结合起来的算法)
这种算法结合了DES和RSA两种算法的优点于一身
原理为:
!.发送者利用DES密钥对重要数据进行加密
2.发送者利用RSA公钥对DES密钥进行加密
3.传送消息
4.接收者收到消息后,利用RSA私钥对经过加密的DES密钥进行解密
5.接收者利用RSA密钥解密解得的DES密钥对重要数据进行解密
在此文中,先产生,本次模拟所要的DES密钥和RSA密钥
然后按照上面五个步骤进行模拟:
1.产生DES密钥
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package digital.envolope.technology;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/**
*
* @author Administrator
*/
public class GenerateDESKey {//产生DES密钥
public static void main(String[] args) {
try {
//密钥生成器
KeyGenerator kg = KeyGenerator.getInstance("DESede"); //采用双重des加密算法
//设置密钥长度为168位
kg.init(168);
//生成密钥
SecretKey k=kg.generateKey();
//将密钥保存在文件中
File dir=new File("digitalEnvolope");
boolean pass= dir.mkdir();//创建目录
if(!pass){
File file=new File(dir,"key.dat");
FileOutputStream out=new FileOutputStream(file);
ObjectOutputStream OOS=new ObjectOutputStream(out);
OOS.writeObject(k);//必须以可序列化对象的形式写入,否则在用ObjectInputStream读取时会抛出异常
out.close();
OOS.close();
}
} catch (Exception ex) {
Logger.getLogger(GenerateDESKey.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
2.产生RSR密钥对
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package digital.envolope.technology;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.File;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Administrator
*/
public class GenKey {
public static void main(String[] args){
try {
//创建密钥对生成器
KeyPairGenerator KPG = KeyPairGenerator.getInstance("RSA");
//初始化密钥生成器
KPG.initialize(1024);
//生成密钥对
KeyPair KP=KPG.genKeyPair();
//获取公钥和密钥
PublicKey pbKey=KP.getPublic();
PrivateKey prKey=KP.getPrivate();
//保存公钥到文件
File file=new File("digitalEnvolope","RSAPublic.dat");
FileOutputStream out=new FileOutputStream(file);
ObjectOutputStream fileOut=new ObjectOutputStream(out);
fileOut.writeObject(pbKey);
//保存密钥到文件
file=new File(("digitalEnvolope","RSAPrivate.dat");
FileOutputStream outPrivate=new FileOutputStream(file);
ObjectOutputStream privateOut=new ObjectOutputStream(outPrivate);
privateOut.writeObject(prKey);
} catch (Exception ex) {
Logger.getLogger(GenKey.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
3.用DES密钥对重要数据进行加密
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package digital.envolope.technology;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
/**
*
* @author Administrator
*/
public class EncryptDESede {//用DESede算法加密数据文件
public static void main(String[] args){
//读取数据文件
File data=new File("digitalEnvolope","business.txt");
try {
FileInputStream dataInput = new FileInputStream(data);
int size=0;//记录文件的字节数
size=dataInput.available();
byte[] dataInputByte=new byte[size];
//读入到字节数组中
dataInput.read(dataInputByte);
//读取des密钥
File encryption=new File("digitalEnvolope","key.dat");
FileInputStream fileInput=new FileInputStream(encryption);
//若在把密钥写入文件时,不是用ObjectOutputStream直接将SecretKey对象写入文件时,在此读取会抛出异常,切记
ObjectInputStream OIS=new ObjectInputStream(fileInput);
Key key=(Key)OIS.readObject();
//取得加密器
Cipher cp=Cipher.getInstance("DESede");
//设置加密模式
cp.init(Cipher.ENCRYPT_MODE, key);
//加密字节
byte encryptByte[]=cp.doFinal(dataInputByte);
FileOutputStream out=new FileOutputStream(new
File("digitalEnvolope","DESEncrypt_data.txt"));
out.write(encryptByte);
//释放系统资源
dataInput.close();
OIS.close();
out.close();
} catch (Exception ex) {
Logger.getLogger(EncryptDESede.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
4.利用RSA公钥对DES密钥进行加密
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package digital.envolope.technology;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*
* @author Administrator
*/
public class RSAEncryptDESEnctyption {//用RSA公钥加密DESede密钥
public static void main(String[] args) {
//创建并初始化密码器
FileInputStream keyFIS = null;//此处不能少
try {
//读取RSA公钥,位于digitalEnvolope文件夹下
File file = new File("digitalEnvolope", "RSAPublic.dat");
keyFIS = new FileInputStream(file);
ObjectInputStream OIS = new ObjectInputStream(keyFIS);
Key key = (Key) OIS.readObject();
//创建并初始化密码器
Cipher cp = Cipher.getInstance("RSA", new BouncyCastleProvider()); //此处不能少
cp.init(Cipher.ENCRYPT_MODE, key);
//读取DESede密钥
file = new File("digitalEnvolope", "key.dat");
FileInputStream dataFIS = new FileInputStream(file);
//取得要加密的数据
int size = dataFIS.available();
byte[] encryptByte = new byte[size];
dataFIS.read(encryptByte);
//建立文件输出流
file = new File("digitalEnvolope", "Enc_RAS.dat");
if (file.exists()) {
file.delete();//如果已经存在则先删除
}
FileOutputStream FOS = new FileOutputStream(file);
//RSA算法必须采用分块加密
//取得RSA加密的块的大小
int blockSize = cp.getBlockSize();
//根据给定的输入长度 inputLen(以字节为单位),返回保存下一个 update 或 doFinal 操作结果所需的输出缓冲区长度(以字节为单位)。
int outputBlockSize = cp.getOutputSize(encryptByte.length);
//确定要加密的次数(加密块的个数)
int leavedSize = encryptByte.length % blockSize;
int blocksNum = leavedSize == 0 ? encryptByte.length / blockSize
: encryptByte.length / blockSize + 1;
byte[] cipherData = new byte[blocksNum * outputBlockSize];
//对每块数据分别加密
for (int i = 0; i < blocksNum; i++) {
if ((encryptByte.length - i * blockSize) > blockSize) {
cp.doFinal(encryptByte, i * blockSize, blockSize, cipherData, i * outputBlockSize);
} else {
cp.doFinal(encryptByte, i * blockSize, encryptByte.length - i * blockSize, cipherData, i * outputBlockSize);
}
}
FOS.write(cipherData);
FOS.close();
} catch (Exception ex) {
Logger.getLogger(RSAEncryptDESEnctyption.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
keyFIS.close();
} catch (IOException ex) {
Logger.getLogger(RSAEncryptDESEnctyption.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
5..接收者收到消息后,利用RSA私钥对经过加密的DES密钥进行解密
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package digital.envolope.technology;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*
* @author Administrator
*/
public class RSADecryptionDESEncryption {//用RSA私钥来解密经过加密的des密钥
public static void main(String[] agrs) {
FileInputStream keyFIS = null;
try {
//读取RSA私钥,位于digitalEnvolope文件夹下
File file = new File("digitalEnvolope", "RSAPrivate.dat");
keyFIS = new FileInputStream(file);
ObjectInputStream OIS = new ObjectInputStream(keyFIS);
Key key = (Key) OIS.readObject();
//创建并初始化密码器
Cipher cp = Cipher.getInstance("RSA", new BouncyCastleProvider()); //此处不能少
cp.init(Cipher.DECRYPT_MODE, key);
//读取经过加密的DES密钥
file=new File("digitalEnvolope","Enc_RAS.dat");
FileInputStream dataFIS = new FileInputStream(file);
//取得要加密的数据
int size = dataFIS.available();
byte[] encryptByte = new byte[size];
dataFIS.read(encryptByte);
//建立输出流
file=new File("digitalEnvolope","Dec_RAS.dat");
FileOutputStream FOS = new FileOutputStream(file);
int blockSize = cp.getBlockSize();
int j = 0;
//分别对各块数据进行解密
while ((encryptByte.length - j * blockSize) > 0) {
FOS.write(cp.doFinal(encryptByte, j * blockSize, blockSize));
j++;
}
FOS.close();
} catch (Exception ex) {
Logger.getLogger(RSADecryptionDESEncryption.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
keyFIS.close();
} catch (IOException ex) {
Logger.getLogger(RSADecryptionDESEncryption.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
6.接收者利用RSA密钥解密解得的DES密钥对重要数据进行解密
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package digital.envolope.technology;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
/**
*
* @author Administrator
*/
public class DecryptDESede {//用RSA密钥解密解得的DES密钥对数据文件进行解密
public static void main(String[] args){
FileInputStream fInput=null;
try {
//读取加密后的数据文件
File f = new File("digitalEnvolope", "DESEncrypt_data.txt");
fInput = new FileInputStream(f);
int size=0;
size=fInput.available();
byte[] encryptDataByte=new byte[size];
fInput.read(encryptDataByte);
//读取解密后的密钥
File des=new File("digitalEnvolope","Dec_RAS.dat");
FileInputStream fileDes=new FileInputStream(des);
ObjectInputStream OIS=new ObjectInputStream(fileDes);
Key key=(Key)OIS.readObject();
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.DECRYPT_MODE, key);
byte[] ptext=cp.doFinal(encryptDataByte);
//把解密后的数据保存起来
f=new File("digitalEnvolope","businessJieMi.dat");
FileOutputStream out=new FileOutputStream(f);
out.write(ptext);
out.close();
fileDes.close();
OIS.close();
} catch (Exception ex) {
Logger.getLogger(DecryptDESede.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
fInput.close();
} catch (IOException ex) {
Logger.getLogger(DecryptDESede.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}