熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

java非對稱加密的源代碼(RSA)

2013-11-23 19:44:57  來源: Java高級技術 

  鑒於rsa加密的重要性和相關源代碼的匮乏經過整理特此貼出需要下載bcprovjdkjar
  
  import javaxcryptoCipher;
  import javasecurity*;
  import javasecurityspecRSAPublicKeySpec;
  import javasecurityspecRSAPrivateKeySpec;
  import javasecurityspecInvalidKeySpecException;
  import javasecurityinterfacesRSAPrivateKey;
  import javasecurityinterfacesRSAPublicKey;
  import javaio*;
  import javamathBigInteger;
  
  /**
  * RSA 工具類提供加密解密生成密鑰對等方法
  * 需要到下載bcprovjdkjar
  *
  */
  public class RSAUtil {
  
  /**
  * 生成密鑰對
  * @return KeyPair
  * @throws EncryptException
  */
  public static KeyPair generateKeyPair() throws EncryptException {
  try {
  KeyPairGenerator keyPairGen = KeyPairGeneratorgetInstance(RSA
  new orgbouncycastlejceproviderBouncyCastleProvider());
  final int KEY_SIZE = ;//沒什麼好說的了這個值關系到塊加密的大小可以更改但是不要太大否則效率會低
  keyPairGeninitialize(KEY_SIZE new SecureRandom());
  KeyPair keyPair = keyPairGengenKeyPair();
  return keyPair;
  } catch (Exception e) {
  throw new EncryptException(egetMessage());
  }
  }
  /**
  * 生成公鑰
  * @param modulus
  * @param publicExponent
  * @return RSAPublicKey
  * @throws EncryptException
  */
  public static RSAPublicKey generateRSAPublicKey(byte[] modulus byte[] publicExponent) throws EncryptException {
  KeyFactory keyFac = null;
  try {
  keyFac = KeyFactorygetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());
  } catch (NoSuchAlgorithmException ex) {
  throw new EncryptException(exgetMessage());
  }
  
  RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus) new BigInteger(publicExponent));
  try {
  return (RSAPublicKey) keyFacgeneratePublic(pubKeySpec);
  } catch (InvalidKeySpecException ex) {
  throw new EncryptException(exgetMessage());
  }
  }
  /**
  * 生成私鑰
  * @param modulus
  * @param privateExponent
  * @return RSAPrivateKey
  * @throws EncryptException
  */
  public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus byte[] privateExponent) throws EncryptException {
  KeyFactory keyFac = null;
  try {
  keyFac = KeyFactorygetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());
  } catch (NoSuchAlgorithmException ex) {
  throw new EncryptException(exgetMessage());
  }
  
  RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus) new BigInteger(privateExponent));
  try {
  return (RSAPrivateKey) keyFacgeneratePrivate(priKeySpec);
  } catch (InvalidKeySpecException ex) {
  throw new EncryptException(exgetMessage());
  }
  }
  /**
  * 加密
  * @param key 加密的密鑰
  * @param data 待加密的明文數據
  * @return 加密後的數據
  * @throws EncryptException
  */
  public static byte[] encrypt(Key key byte[] data) throws EncryptException {
  try {
  Cipher cipher = CiphergetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());
  cipherinit(CipherENCRYPT_MODE key);
  int blockSize = ciphergetBlockSize();//獲得加密塊大小加密前數據為個byte而key_size= 加密塊大小為 byte加密後為個byte;因此共有個加密塊第一個 byte第二個為個byte
  int outputSize = ciphergetOutputSize(datalength);//獲得加密塊加密後塊大小
  int leavedSize = datalength % blockSize;
  int blocksSize = leavedSize != ? datalength / blockSize + : datalength / blockSize;
  byte[] raw = new byte[outputSize * blocksSize];
  int i = ;
  while (datalength i * blockSize > ) {
  if (datalength i * blockSize > blockSize)
  cipherdoFinal(data i * blockSize blockSize raw i * outputSize);
  else
  cipherdoFinal(data i * blockSize datalength i * blockSize raw i * outputSize);
  //這裡面doUpdate方法不可用查看源代碼後發現每次doUpdate後並沒有什麼實際動作除了把byte[]放到ByteArrayOutputStream中而最後doFinal的時候才將所有的byte[]進行加密可是到了此時加密塊大小很可能已經超出了OutputSize所以只好用dofinal方法
  
  i++;
  }
  return raw;
  } catch (Exception e) {
  throw new EncryptException(egetMessage());
  }
  }
  /**
  * 解密
  * @param key 解密的密鑰
  * @param raw 已經加密的數據
  * @return 解密後的明文
  * @throws EncryptException
  */
  public static byte[] decrypt(Key key byte[] raw) throws EncryptException {
  try {
  Cipher cipher = CiphergetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());
  cipherinit(cipherDECRYPT_MODE key);
  int blockSize = ciphergetBlockSize();
  ByteArrayOutputStream bout = new ByteArrayOutputStream();
  int j = ;
  
  while (rawlength j * blockSize > ) {
  boutwrite(cipherdoFinal(raw j * blockSize blockSize));
  j++;
  }
  return bouttoByteArray();
  } catch (Exception e) {
  throw new EncryptException(egetMessage());
  }
  }
  /**
  *
  * @param args
  * @throws Exception
  */
  public static void main(String[] args) throws Exception {
  File file = new File(l);
  FileInputStream in = new FileInputStream(file);
  ByteArrayOutputStream bout = new ByteArrayOutputStream();
  byte[] tmpbuf = new byte[];
  int count = ;
  while ((count = inread(tmpbuf)) != ) {
  boutwrite(tmpbuf count);
  tmpbuf = new byte[];
  }
  inclose();
  byte[] orgData = bouttoByteArray();
  KeyPair keyPair = RSAUtilgenerateKeyPair();
  RSAPublicKey pubKey = (RSAPublicKey) keyPairgetPublic();
  RSAPrivateKey priKey = (RSAPrivateKey) keyPairgetPrivate();
  
  byte[] pubModBytes = pubKeygetModulus()toByteArray();
  byte[] pubPubExpBytes = pubKeygetPublicExponent()toByteArray();
  byte[] priModBytes = priKeygetModulus()toByteArray();
  byte[] priPriExpBytes = priKeygetPrivateExponent()toByteArray();
  RSAPublicKey recoveryPubKey = RSAUtilgenerateRSAPublicKey(pubModBytespubPubExpBytes);
  RSAPrivateKey recoveryPriKey = RSAUtilgenerateRSAPrivateKey(priModBytespriPriExpBytes);
  
  byte[] raw = RSAUtilencrypt(priKey orgData);
  file = new File(encrypt_resultdat);
  OutputStream out = new FileOutputStream(file);
  outwrite(raw);
  outclose();
  byte[] data = RSAUtildecrypt(recoveryPubKey raw);
  file = new File(l);
  out = new FileOutputStream(file);
  outwrite(data);
  outflush();
  outclose();
  }
  }
  
  加密可以用公鑰解密用私鑰或者加密用私鑰通常非對稱加密是非常消耗資源的因此可以對大數據用對稱加密如des(具體代碼可以看我以前發的貼子)而對其對稱密鑰進行非對稱加密這樣既保證了數據的安全還能保證效率
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27391.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.