RSAUtil


/**
 *   @(#) RSAUtil.java
 */
 package edu.hust.util.security;

import java.math.*;
import java.io.*;
import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;
import javax.crypto.*;

/**
 *    EncryptException is an exception class from exception, handles any exceptions that
 *    may happen in the encryption/descryption.
 */
class EncryptException extends Exception {
   /**
    *  Construct a new EncryptException
    */
    public EncryptException() {
         super();
      }
    
      /**
       *  Construct a new EncryptException
       *  @param msg exception message
       */
      public EncryptException( String msg ) {
       super( msg );
      }
     
      /**
       *  Construct a new EncryptException
       *  @ex exception
       */
      public EncryptException( Throwable ex ) {
       super( ex );
      }
 }

      /**
       *   RSAUtil is a util class for implementing RSA algorithm,
       *   which needs bcprov-jdk1.4.jar being installed into CLASSPATH
       *   @author quickpoint
       *   @version 1.0 06/22/2005
       */
public class RSAUtil {
 /**
  *   Generate key pair
  *   @return key pair
  *   @exception EncryptException throws when any exception happened in the generation
  */
 public static KeyPair generateKeyPair()
             throws EncryptException
 {
      try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                                              "RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());
        final int KEY_SIZE = 1024;
        keyPairGenerator.initialize( KEY_SIZE, new SecureRandom());
        KeyPair keyPair = keyPairGenerator.genKeyPair();
       
        return keyPair;
      } catch ( Exception ex ) {
       throw new EncryptException(ex);
      }
 }
 
 /**
  *   Generate RSA public key
  *   @return RSA public key
  *   @exception when any exception happended in the generation.
  */
 public static RSAPublicKey generateRSAPublicKey( byte[] modules, byte[] publicExponent )
              throws EncryptException {
        KeyFactory keyFac = null;
        try {
         keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
         
         
         RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger( modules), new BigInteger( publicExponent));
         
         return (RSAPublicKey) keyFac.generatePublic( pubKeySpec);
        } catch ( Exception ex ) {
         throw new EncryptException( ex );
        }          
 }
 
 /**
  *   Generate RSA private key
  *   @return private key
  *   @exception EncryptException throws when any exception happened in the generation
  */
 public static RSAPrivateKey generateRSAPrivateKey( byte[] modules, byte[] privateExponent )
              throws EncryptException {
               
        KeyFactory keyFac = null;
        try {
         keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
         
         RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec( new BigInteger( modules), new BigInteger( privateExponent ) );
         
         return (RSAPrivateKey ) keyFac.generatePrivate( priKeySpec );
        } catch ( Exception ex ) {
          throw new EncryptException( ex );
        }
 }
 
 /**
  *   Doing encryption with RSA
  *   @return cipher text
  *   @exception EncryptException throws when any exception happened in encryption
  */
    public static byte[] encrypt(Key key, byte[] data) throws EncryptException {
        try {
            Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, key);
            int blockSize = cipher.getBlockSize();
            int outputSize = cipher.getOutputSize(data.length);
            int leavedSize = data.length % blockSize;
            int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
            byte[] raw = new byte[outputSize * blocksSize];
            int i = 0;
            while (data.length - i * blockSize > 0) {
                if (data.length - i * blockSize > blockSize)
                    cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
                else
                    cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
                i++;
            }
            return raw;
        } catch (Exception ex) {
            throw new EncryptException(ex);
        }
    }
   
    
    /**
     *   Doing decryption
     *   @return plain text
     *   @exception throws when any exception happened in the decryption.
     */ 
 public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {
        try {
            Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(cipher.DECRYPT_MODE, key);
            int blockSize = cipher.getBlockSize();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
            int j = 0;

            while (raw.length - j * blockSize > 0) {
                bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                j++;
            }
            return bout.toByteArray();
        } catch (Exception ex) {
            throw new EncryptException(ex);
        }
    }
   
    /////////////////////////////////////////////////////////
    //                  Text Handler
    /////////////////////////////////////////////////////////
    /**
     *   Store text
     *  
     */
    public static boolean storeText( byte[] text, String fileName ) {
     try {
      OutputStream out = new FileOutputStream( fileName );
      out.write( text );
      out.flush();
      out.close();
      return true;
     } catch ( FileNotFoundException fileNotFoundEx ) {
          fileNotFoundEx.printStackTrace();
     } catch ( IOException ioEx ) {
       ioEx.printStackTrace();
     }
     
     return false;
    }
   
    ///////////////////////////////////////////////////////////////
    //                   Key handler
    ///////////////////////////////////////////////////////////////
    /**
     *
     */
     public static boolean storeKey( Key key, String fileName ) {
           try {
            ObjectOutputStream out = new ObjectOutputStream( 
                                            new FileOutputStream( fileName ));
            out.writeObject( key );
            out.close();                     
            return true;           
           } catch ( FileNotFoundException fileNotFoundEx ) {
             fileNotFoundEx.printStackTrace();
           } catch ( IOException ioEx ) {
             ioEx.printStackTrace();
           }
          
             return false;
     }
    
    /**
     *     
     */
    public static RSAPublicKey loadPublicKey( String fileName ) {
        RSAPublicKey rsaPubKey = null;
     try {
      ObjectInputStream in = new ObjectInputStream(
                                       new FileInputStream( fileName ));
            rsaPubKey = ( RSAPublicKey ) in.readObject();                       
     }  catch ( ClassNotFoundException classNotFoundEx ) {
      classNotFoundEx.printStackTrace();
     }  catch ( FileNotFoundException fileNotFoundEx ) {
      fileNotFoundEx.printStackTrace();
     } catch ( IOException ioEx ) {
      ioEx.printStackTrace();
     }
        return rsaPubKey;
    }
 
    /**
     *
     */
    public static RSAPrivateKey loadPrivateKey( String fileName ) {
     RSAPrivateKey rsaPriKey = null;
     try {
      ObjectInputStream in = new ObjectInputStream(
                                    new FileInputStream( fileName ));
      rsaPriKey = ( RSAPrivateKey ) in.readObject();                             
     } catch ( ClassNotFoundException classNotFoundEx ) {
       classNotFoundEx.printStackTrace( );
     } catch ( FileNotFoundException fileNotFoundEx ) {
       fileNotFoundEx.printStackTrace( );
     } catch ( IOException ioEx ) {
      ioEx.printStackTrace();
     }
         return rsaPriKey;
    } 
   
    // main, just for test
 public static void main( String[] args ) {
  String testFileName = "RSAUtil.java";
  String cipherTextFileName = "cipherText.txt";
  String plainTextFileName = "plainText.txt";
  String pubKeyFileName = "pubkey.txt";
  String priKeyFileName = "prikey.txt";
  
  try {
      System.out.println("load test file content...");
   FileInputStream in = new FileInputStream( testFileName );
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   byte[] tmpBuf = new byte[1024];
   int count = 0;
   while( ( count = in.read(tmpBuf)) != -1 ) {
    out.write(tmpBuf, 0, count );
    tmpBuf = new byte[1024];
   }
   in.close();
   out.close();
   
   byte[] orgData = out.toByteArray();
   
   System.out.println("generate key pair");
   KeyPair keyPair = RSAUtil.generateKeyPair();
   RSAPublicKey pubKey = (RSAPublicKey ) keyPair.getPublic();
   RSAPrivateKey priKey = (RSAPrivateKey)keyPair.getPrivate();
   
   /*
   byte[] pubModBytes = pubKey.getModulus().toByteArray();
   byte[] priModBytes = priKey.getModulus().toByteArray();
   byte[] pubPubExponent = pubKey.getPublicExponent().toByteArray();
   byte[] priPriExponent = priKey.getPrivateExponent().toByteArray();
   
   RSAPublicKey recoverPubKey = RSAUtil.generateRSAPublicKey( pubModBytes, pubPubExponent );
   RSAPrivateKey recoverPriKey = RSAUtil.generateRSAPrivateKey( priModBytes, priPriExponent );
   */
   System.out.println( "encrypting...");
   byte[] raw = RSAUtil.encrypt( pubKey, orgData);
   System.out.println( "store key...");
   storeKey(pubKey, pubKeyFileName );
   storeKey(priKey, priKeyFileName );
         System.out.println( "store cipher text...");
         storeText( raw, cipherTextFileName );
        
         ////////////////////////////////////////
         // decrypt
         System.out.println( "load pri key" );
         priKey = loadPrivateKey( priKeyFileName ); 
         System.out.println( "decrypting...");
        byte[] data = RSAUtil.decrypt( priKey , raw );
        System.out.println( "store plain text...");
      storeText( data, plainTextFileName );
    } catch ( Exception ex ) {
   ex.printStackTrace();
  }
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值