JAVA的会话密钥程序

原创 2004年06月23日 18:25:00

/***************
运行本程序你需要下载JCE,Bouncy Castle的JCE with Provider and Lightweight API
网止是 http://www.bouncycastle.org 
配置如下:
在WINDOWS中,你需要把下载的bcprov-jdk14-119.jar文件拷贝到两个地方:
一个在你安装的JDK目录中,比如说我的是C:/j2sdk1.4.0-rc/jre/lib/ext
另一个在你的JDK运行环境中,我的是在
C:/Program Files/Java/j2re1.4.0-rc/lib/ext;
另外还要在对两个java.security进行修改:
我的在 C:/j2sdk1.4.0-rc/jre/lib/security/java.security;
C:/Program Files/Java/j2re1.4.0-rc/lib/security/java.security;
在java.security中加入 security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider 
如果一切顺利,你就可以运行本程序了。

该程序具有对你的文件加解密功能。需要你指定的数据,程序中已给了接口。
比如说你指定了要加密的文件名"4.txt",加密后的文件存放位置"6.txt",
还有口令password如"liufeng"后,运行该程序,那么"6.txt" 中将是"4.txt"的密文。
注意口令是解密的钥匙,不要忘记。
其他解密过程自己参考。

本程序利用会话密钥加密,提供很多接口。如果你项目中需要加密过程,可以稍加改进为你所用
*/

import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.util.*;


public class FileEncryptorRSA {


private static final int ITERATIONS=1000;//计算次数,在加盐中用到
private static byte[] publicKeyBytes;//公钥
private static byte[] privateKeyBytes;//私钥
private static String SessionKey;//会话密钥
public static String ENCRYPT_PRIVATEKEY_FILE="1.txt";//该文件放置加密的私钥 
private static String TEXT_FILE="4.txt";//要加密的文件
private static String ENCRPTOR_TEXT_FILE="5.txt";//被加密后的文件
private static String DENCRYPTOR_TEXT_FILE="6.txt";//解密后的文件
private static String password="12345678";//口令用于加密私钥


public void setTEXT_FILE(String fileName){
TEXT_FILE=fileName;
}
public void setENCRYPT_PRIVATEKEY_FILE(String fileName){
ENCRYPT_PRIVATEKEY_FILE=fileName;
}
public String getENCRYPT_PRIVATEKEY_FILE(){
return ENCRYPT_PRIVATEKEY_FILE;
}

public void setENCRPTOR_TEXT_FILE(String fileName){
ENCRPTOR_TEXT_FILE=fileName;
}
public String getENCRPTOR_TEXT_FILE(){
return ENCRPTOR_TEXT_FILE;
}
public void setDENCRYPTOR_TEXT_FILE(String fileName){
DENCRYPTOR_TEXT_FILE=fileName;
}
public String getDENCRYPTOR_TEXT_FILE(){
return DENCRYPTOR_TEXT_FILE;
}
public void setPassword(String password){
this.password=password;
}


//create a RSA secretKey
public static void createKey()throws Exception{
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair=keyPairGenerator.genKeyPair();
//得到公钥的字节数组
publicKeyBytes=keyPair.getPublic().getEncoded();
//得到私钥
byte[] privateKeyBytes=keyPair.getPrivate().getEncoded();
byte[] encrytedPrivatekey=passwordEncrypt(password.toCharArray(),privateKeyBytes);
FileOutputStream fos=new FileOutputStream(ENCRYPT_PRIVATEKEY_FILE);
fos.write(encrytedPrivatekey);
fos.close();
}



//通过给的口令加密私钥
private static byte[] passwordEncrypt(char[] password,byte[] privateKeyBytes)
throws Exception{
//create 8 byte salt 
byte[] salt=new byte[8];
Random random=new Random();
random.nextBytes(salt);
//create a PBE key and cipher
PBEKeySpec keySpec=new PBEKeySpec(password);
SecretKeyFactory keyFactory=SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
SecretKey key=keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec=new PBEParameterSpec(salt,ITERATIONS);
Cipher cipher=Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
cipher.init(Cipher.ENCRYPT_MODE,key,paramSpec);
//Encrypt the byte[]
byte[] cipherPriKey=cipher.doFinal(privateKeyBytes);
//write out salt ,and then the cipherPriKey
ByteArrayOutputStream baos=new ByteArrayOutputStream();
baos.write(salt);
baos.write(cipherPriKey);
return baos.toByteArray();




//用会话密钥加密给定的文件,然后用公钥加密会话密钥,并存入文件中
//最后加密后的文件由密钥长度+已加密的密钥(会话密钥)+密文
public static void encrypt()throws Exception{

//转换成RSA密钥
X509EncodedKeySpec keySpec=new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory=KeyFactory.getInstance("RSA");
PublicKey publickey=keyFactory.generatePublic(keySpec);
//打开存贮密文的文件
DataOutputStream output=new DataOutputStream(new FileOutputStream(ENCRPTOR_TEXT_FILE));
//创建RSA的CIpher
Cipher rsaCipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.ENCRYPT_MODE,publickey);
//创建会话密钥(Rijndael)
KeyGenerator rijndaelKeyGenerator=KeyGenerator.getInstance("Rijndael");
rijndaelKeyGenerator.init(256);
Key rijndaelKey=rijndaelKeyGenerator.generateKey();
//公钥加密会话密钥 
byte[] encodedKeyBytes=rsaCipher.doFinal(rijndaelKey.getEncoded());
output.writeInt(encodedKeyBytes.length);
output.write(encodedKeyBytes);
//产生IV向量
SecureRandom random=new SecureRandom();
byte[] iv=new byte[16];
random.nextBytes(iv);
output.write(iv);

//加密正文
IvParameterSpec spec=new IvParameterSpec(iv);
Cipher symmetricCipher=Cipher.getInstance("Rijndael/CBC/PKCS5Padding");
symmetricCipher.init(Cipher.ENCRYPT_MODE,rijndaelKey,spec);
CipherOutputStream cos=new CipherOutputStream(output,symmetricCipher);
FileInputStream input=new FileInputStream(TEXT_FILE);

int theByte=0;
while((theByte=input.read())!=-1){
cos.write(theByte);
}
input.close();
cos.close();
return;
}



//得到私钥
private static byte[] passwordDecrypt(char[] password,byte[] ciphertext)
throws Exception{
byte[] salt=new byte[8];
ByteArrayInputStream bais=new ByteArrayInputStream(ciphertext);
bais.read(salt,0,8);
byte[] remainingCiphertext=new byte[ciphertext.length-8];
bais.read(remainingCiphertext,0,ciphertext.length-8);
PBEKeySpec keySpec=new PBEKeySpec(password);
SecretKeyFactory keyFactory=SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
SecretKey key=keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec=new PBEParameterSpec(salt,ITERATIONS);
Cipher cipher=Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
cipher.init(Cipher.DECRYPT_MODE,key,paramSpec);
return cipher.doFinal(remainingCiphertext);
}


//解密加密的文件 
public static void decrypt()
throws Exception{
FileInputStream fis=new FileInputStream(ENCRYPT_PRIVATEKEY_FILE);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int theByte=0;
while((theByte=fis.read())!=-1){
baos.write(theByte);
}
fis.close();
//得到被加密的私钥
byte[] keyBytes=baos.toByteArray();
baos.close();
//得到私钥
byte[] sKey=passwordDecrypt(password.toCharArray(),keyBytes);
//产生RSA私钥
PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(sKey);
KeyFactory keyFactory=KeyFactory.getInstance("RSA");
PrivateKey privateKey=keyFactory.generatePrivate(keySpec);
Cipher rsaCipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

DataInputStream dis=new DataInputStream(new FileInputStream(ENCRPTOR_TEXT_FILE));
//读密文中密码长度和密码 
byte[] encryptedKeyBytes=new byte[dis.readInt()];
dis.readFully(encryptedKeyBytes);
rsaCipher.init(Cipher.DECRYPT_MODE,privateKey);
byte[] rijdaelKeyBytes=rsaCipher.doFinal(encryptedKeyBytes);
//得到会话密钥
SecretKey rijndaelKey=new SecretKeySpec(rijdaelKeyBytes,"Rijndael");
byte[] iv=new byte[16];
dis.read(iv);
IvParameterSpec spec=new IvParameterSpec(iv);
//用会话密钥解密正文
Cipher cipher=Cipher.getInstance("Rijndael/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,rijndaelKey,spec);

CipherInputStream cis=new CipherInputStream(dis,cipher);
FileOutputStream fos=new FileOutputStream(DENCRYPTOR_TEXT_FILE);

theByte=0;
while((theByte=cis.read())!=-1){
fos.write(theByte);
}
cis.close();
fos.close();
return;
}
public static void main(String[] args)throws Exception{
createKey();
encrypt();
decrypt();
}
}


一个用JAVA开发的会话密钥程序

/* 运行本程序你需要下载JCE,Bouncy Castle的JCE with Provider and Lightweight API 网址是 http://www.bouncycastle.org...
  • yczzcy
  • yczzcy
  • 2006年04月26日 17:58
  • 655

“一次一密”会话密钥的设计

1引言会话密钥用于在网络通讯过程中实现端到端的信息加密,一般是在每次会话时临时产生,一次会话结束后被销毁。 现在普遍采用的生成会话密钥的方法是基于公钥加密算法,首先一方向另一方提供自己的证书,另一方...
  • LVXIANGAN
  • LVXIANGAN
  • 2013年11月29日 18:20
  • 2228

使用公开密钥机制进行会话密钥

当我们在进行通信的时候,常常需要在C/S两端分配一个会话密钥,然后利用对称密码算法对通信的数据加密,当然了,也可以使用非对称加密算法,但是非对称加密会使加密速度降低了一个数量级,因此并不适用。那么如何...
  • zdavb
  • zdavb
  • 2016年03月09日 23:59
  • 1095

公钥、密钥、SSL、会话密钥的简单解释

im安全层协议设计(instant message 即时通讯)消息的保密性非常重要 ,谁都不希望自己聊天内容被看到,所以安全层是必不可少的。1、SSL证书管理微微复杂,代价有点高。2、自行加解密自己来...
  • xybelieve1990
  • xybelieve1990
  • 2017年02月07日 18:27
  • 1044

密钥协商基础知识

不同的密钥协商算法TLS-RSA这种算法,客户端指定副主密钥,然后加密传输 TLS-RSA:在这个场景下,PreMasterSecret是由客户端指定的,并用RSA公钥加密发送给服务器。服务器不...
  • a11211058
  • a11211058
  • 2016年12月12日 15:18
  • 1383

SSH协议分析以及在linux下免秘钥登录流程

摘要 SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定;SSH 为建立在应用层和传输层基础上的安全协议。SSH 是目前...
  • liyongke89
  • liyongke89
  • 2016年04月27日 18:10
  • 1048

ssl运行机制中,为什么不直接采用pms作为会话密钥

阮一峰写了一篇不错的文章介绍ssl的运行机制 http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html 对于”为什么一定要用三个随机数,来生成会话密钥”...
  • doraeimo
  • doraeimo
  • 2014年02月08日 22:16
  • 1532

SCP02会话密钥计算过程

描述GP规范中,SCP02会话秘钥的计算过程 #LoadKeyGP_AEA57E0042780CEBBBD7CA2FE63CFF05 888D0508C5AF62E085F7D3FB713D...
  • ls__today
  • ls__today
  • 2018年01月28日 17:17
  • 39

Kerberos

Kerberos是由美国麻省理工学院提出的基于可信赖的第三方的认证系统。Kerberos提供了一种在开放式网络环境下进行身份认证的方法,它使网络上的用户可以相互证明自己的身份。  Kerberos采用...
  • luxuejuncarl
  • luxuejuncarl
  • 2007年04月15日 15:12
  • 935

图解密码技术

图解密码技术学习笔记 第一章 环游密码世界 1.对称密码和公钥密码 对称密码:指加密和解密时使用同一密钥的方式 公钥密码:指在加密和解密时使用不同密钥方式,又称非对称密码 2.其他密码技术 单向散列函...
  • molu_chase
  • molu_chase
  • 2016年07月07日 11:01
  • 477
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA的会话密钥程序
举报原因:
原因补充:

(最多只允许输入30个字)