//package /* 运行本程序你需要下载JCE,Bouncy Castle的JCE with Provider and Lightweight API 网止是 http://www.bouncycastle.org 配置如下: 在WIND" />
龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

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

时间:2009-12-23 15:42来源:未知 作者:admin 点击:
分享到:
?XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" /> //package /* 运行本程序你需要下载JCE,Bouncy Castle的JCE with Provider and Lightweight API 网止是 http://www.bouncycastle.org 配置如下: 在WIND

<?XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" /> 

//package
  /*
  运行本程序你需要下载JCE,Bouncy Castle的JCE with Provider and Lightweight API
  网止是 http://www.bouncycastle.org
  配置如下:
  在WINDOWS中,你需要把下载的bcprov-jdk14-119.jar文件拷贝到两个地方:
  一个在你安装的JDK目录中,比如说我的是C:j2sdk1.4.0-rcjrelibext
  另一个在你的JDK运行环境中,我的是在
  C:Program FilesJavaj2re1.4.0-rclibext;
  另外还要在对两个java.security进行修改:
  我的在 C:j2sdk1.4.0-rcjrelibsecurityjava.security;
  C:Program FilesJavaj2re1.4.0-rclibsecurityjava.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="liufeng";//口令用于加密私钥
  
  
  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();
  }
  }
  


  
精彩图集

赞助商链接