`

java非对称加密

    博客分类:
  • pki
阅读更多
  1.  import Javax.crypto.Cipher;   
  2.   import java.security.*;   
  3.   import java.security.spec.RSAPublicKeySpec;   
  4.   import java.security.spec.RSAPrivateKeySpec;   
  5.   import java.security.spec.InvalidKeySpecException;   
  6.   import java.security.interfaces.RSAPrivateKey;   
  7.   import java.security.interfaces.RSAPublicKey;   
  8.   import java.io.*;   
  9.   import java.math.BigInteger;   
  10.      
  11.   /**  
  12.   * RSA 工具类。提供加密,解密,生成密钥对等方法。  
  13.   * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。  
  14.   *  
  15.   */  
  16.   public class RSAUtil {   
  17.      
  18.   /**  
  19.   * 生成密钥对  
  20.   * @return KeyPair  
  21.   * @throws EncryptException  
  22.   */  
  23.   public static KeyPair generateKeyPair() throws EncryptException {   
  24.   try {   
  25.   KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",   
  26.   new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  27.   final int KEY_SIZE = 1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低   
  28.   keyPairGen.initialize(KEY_SIZE, new SecureRandom());   
  29.   KeyPair keyPair = keyPairGen.genKeyPair();   
  30.   return keyPair;   
  31.   } catch (Exception e) {   
  32.   throw new EncryptException(e.getMessage());   
  33.   }   
  34.   }   
  35.   /**  
  36.   * 生成公钥  
  37.   * @param modulus  
  38.   * @param publicEXPonent  
  39.   * @return RSAPublicKey  
  40.   * @throws EncryptException  
  41.   */  
  42.   public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws EncryptException {   
  43.   KeyFactory keyFac = null;   
  44.   try {   
  45.   keyFac = KeyFactory.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  46.   } catch (NoSUChAlgorithmException ex) {   
  47.   throw new EncryptException(ex.getMessage());   
  48.   }   
  49.      
  50.   RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));   
  51.   try {   
  52.   return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);   
  53.   } catch (InvalidKeySpecException ex) {   
  54.   throw new EncryptException(ex.getMessage());   
  55.   }   
  56.   }   
  57.   /**  
  58.   * 生成私钥  
  59.   * @param modulus  
  60.   * @param privateExponent  
  61.   * @return RSAPrivateKey  
  62.   * @throws EncryptException  
  63.   */  
  64.   public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws EncryptException {   
  65.   KeyFactory keyFac = null;   
  66.   try {   
  67.   keyFac = KeyFactory.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  68.   } catch (NoSuchAlgorithmException ex) {   
  69.   throw new EncryptException(ex.getMessage());   
  70.   }   
  71.      
  72.   RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));   
  73.   try {   
  74.   return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);   
  75.   } catch (InvalidKeySpecException ex) {   
  76.   throw new EncryptException(ex.getMessage());   
  77.   }   
  78.   }   
  79.   /**  
  80.   * 加密  
  81.   * @param key 加密的密钥  
  82.   * @param data 待加密的明文数据  
  83.   * @return 加密后的数据  
  84.   * @throws EncryptException  
  85.   */  
  86.   public static byte[] encrypt(Key key, byte[] data) throws EncryptException {   
  87.   try {   
  88.   Cipher cipher = Cipher.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  89.   cipher.init(Cipher.ENCRYPT_MODE, key);   
  90.   int blockSize = cipher.getBlockSize();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;因此共有2个加密块,第一个127 byte第二个为1个byte   
  91.   int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小   
  92.   int leavedSize = data.length % blockSize;   
  93.   int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;   
  94.   byte[] raw = new byte[outputSize * blocksSize];   
  95.   int i = 0;   
  96.   while (data.length - i * blockSize > 0) {   
  97.   if (data.length - i * blockSize > blockSize)   
  98.   cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);   
  99.   else  
  100.   cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);   
  101.   //这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。   
  102.      
  103.   i++;   
  104.   }   
  105.   return raw;   
  106.   } catch (Exception e) {   
  107.   throw new EncryptException(e.getMessage());   
  108.   }   
  109.   }   
  110.   /**  
  111.   * 解密  
  112.   * @param key 解密的密钥  
  113.   * @param raw 已经加密的数据  
  114.   * @return 解密后的明文  
  115.   * @throws EncryptException  
  116.   */  
  117.   public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {   
  118.   try {   
  119.   Cipher cipher = Cipher.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  120.   cipher.init(cipher.DECRYPT_MODE, key);   
  121.   int blockSize = cipher.getBlockSize();   
  122.   ByteArrayOutputStream bout = new ByteArrayOutputStream(64);   
  123.   int j = 0;   
  124.      
  125.   while (raw.length - j * blockSize > 0) {   
  126.   bout.write(cipher.doFinal(raw, j * blockSize, blockSize));   
  127.   j++;   
  128.   }   
  129.   return bout.toByteArray();   
  130.   } catch (Exception e) {   
  131.   throw new EncryptException(e.getMessage());   
  132.   }   
  133.   }   
  134.   /**  
  135.   *  
  136.   * @param args  
  137.   * @throws Exception  
  138.   */  
  139.   public static void main(String[] args) throws Exception {   
  140.   File file = new File("test.Html");   
  141.   FileInputStream in = new FileInputStream(file);   
  142.   ByteArrayOutputStream bout = new ByteArrayOutputStream();   
  143.   byte[] tmpbuf = new byte[1024];   
  144.   int count = 0;   
  145.   while ((count = in.read(tmpbuf)) != -1) {   
  146.   bout.write(tmpbuf, 0, count);   
  147.   tmpbuf = new byte[1024];   
  148.   }   
  149.   in.close();   
  150.   byte[] orgData = bout.toByteArray();   
  151.   KeyPair keyPair = RSAUtil.generateKeyPair();   
  152.   RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();   
  153.   RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();   
  154.      
  155.   byte[] pubModBytes = pubKey.getModulus().toByteArray();   
  156.   byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();   
  157.   byte[] priModBytes = priKey.getModulus().toByteArray();   
  158.   byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();   
  159.   RSAPublicKey recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);   
  160.   RSAPrivateKey recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);   
  161.      
  162.   byte[] raw = RSAUtil.encrypt(priKey, orgData);   
  163.   file = new File("encrypt_result.dat");   
  164.   OutputStream out = new FileOutputStream(file);   
  165.   out.write(raw);   
  166.   out.close();   
  167.   byte[] data = RSAUtil.decrypt(recoveryPubKey, raw);   
  168.   file = new File("decrypt_result.html");   
  169.   out = new FileOutputStream(file);   
  170.   out.write(data);   
  171.   out.flush();   
  172.   out.close();   
  173.   }   
  174.   }  
  import Javax.crypto.Cipher;
  import java.security.*;
  import java.security.spec.RSAPublicKeySpec;
  import java.security.spec.RSAPrivateKeySpec;
  import java.security.spec.InvalidKeySpecException;
  import java.security.interfaces.RSAPrivateKey;
  import java.security.interfaces.RSAPublicKey;
  import java.io.*;
  import java.math.BigInteger;
  
  /**
  * RSA 工具类。提供加密,解密,生成密钥对等方法。
  * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
  *
  */
  public class RSAUtil {
  
  /**
  * 生成密钥对
  * @return KeyPair
  * @throws EncryptException
  */
  public static KeyPair generateKeyPair() throws EncryptException {
  try {
  KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
  new org.bouncycastle.jce.provider.BouncyCastleProvider());
  final int KEY_SIZE = 1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
  keyPairGen.initialize(KEY_SIZE, new SecureRandom());
  KeyPair keyPair = keyPairGen.genKeyPair();
  return keyPair;
  } catch (Exception e) {
  throw new EncryptException(e.getMessage());
  }
  }
  /**
  * 生成公钥
  * @param modulus
  * @param publicEXPonent
  * @return RSAPublicKey
  * @throws EncryptException
  */
  public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws EncryptException {
  KeyFactory keyFac = null;
  try {
  keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
  } catch (NoSUChAlgorithmException ex) {
  throw new EncryptException(ex.getMessage());
  }
  
  RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
  try {
  return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
  } catch (InvalidKeySpecException ex) {
  throw new EncryptException(ex.getMessage());
  }
  }
  /**
  * 生成私钥
  * @param modulus
  * @param privateExponent
  * @return RSAPrivateKey
  * @throws EncryptException
  */
  public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws EncryptException {
  KeyFactory keyFac = null;
  try {
  keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
  } catch (NoSuchAlgorithmException ex) {
  throw new EncryptException(ex.getMessage());
  }
  
  RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));
  try {
  return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
  } catch (InvalidKeySpecException ex) {
  throw new EncryptException(ex.getMessage());
  }
  }
  /**
  * 加密
  * @param key 加密的密钥
  * @param data 待加密的明文数据
  * @return 加密后的数据
  * @throws EncryptException
  */
  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();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;因此共有2个加密块,第一个127 byte第二个为1个byte
  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);
  //这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。
  
  i++;
  }
  return raw;
  } catch (Exception e) {
  throw new EncryptException(e.getMessage());
  }
  }
  /**
  * 解密
  * @param key 解密的密钥
  * @param raw 已经加密的数据
  * @return 解密后的明文
  * @throws EncryptException
  */
  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 e) {
  throw new EncryptException(e.getMessage());
  }
  }
  /**
  *
  * @param args
  * @throws Exception
  */
  public static void main(String[] args) throws Exception {
  File file = new File("test.Html");
  FileInputStream in = new FileInputStream(file);
  ByteArrayOutputStream bout = new ByteArrayOutputStream();
  byte[] tmpbuf = new byte[1024];
  int count = 0;
  while ((count = in.read(tmpbuf)) != -1) {
  bout.write(tmpbuf, 0, count);
  tmpbuf = new byte[1024];
  }
  in.close();
  byte[] orgData = bout.toByteArray();
  KeyPair keyPair = RSAUtil.generateKeyPair();
  RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
  RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
  
  byte[] pubModBytes = pubKey.getModulus().toByteArray();
  byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
  byte[] priModBytes = priKey.getModulus().toByteArray();
  byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
  RSAPublicKey recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
  RSAPrivateKey recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
  
  byte[] raw = RSAUtil.encrypt(priKey, orgData);
  file = new File("encrypt_result.dat");
  OutputStream out = new FileOutputStream(file);
  out.write(raw);
  out.close();
  byte[] data = RSAUtil.decrypt(recoveryPubKey, raw);
  file = new File("decrypt_result.html");
  out = new FileOutputStream(file);
  out.write(data);
  out.flush();
  out.close();
  }
  }

   
  加密可以用公钥,解密用私钥;或者加密用私钥。通常非对称加密是非常消耗资源的,因此可以对大数据用对称加密如:des(具体代码可以看我以前发的贴子),而对其对称密钥进行非对称加密,这样既保证了数据的安全,还能保证效率。

Java代码 复制代码
  1. import javax.crypto.Cipher;   
  2. import java.security.*;   
  3. import java.security.spec.RSAPublicKeySpec;   
  4. import java.security.spec.RSAPrivateKeySpec;   
  5. import java.security.spec.InvalidKeySpecException;   
  6. import java.security.interfaces.RSAPrivateKey;   
  7. import java.security.interfaces.RSAPublicKey;   
  8. import java.io.*;   
  9. import java.math.BigInteger;   
  10.     
  11. public class RSAUtil {   
  12.     
  13.     /**  
  14.      *   * 生成密钥对  
  15.      *   * @return KeyPair  
  16.      *   * @throws EncryptException  
  17.      */  
  18.     public static KeyPair generateKeyPair() throws EncryptException {   
  19.         try {   
  20.             KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",   
  21.                     new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  22.             final int KEY_SIZE = 1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低   
  23.             keyPairGen.initialize(KEY_SIZE, new SecureRandom());   
  24.             KeyPair keyPair = keyPairGen.genKeyPair();   
  25.             return keyPair;   
  26.         } catch (Exception e) {   
  27.             throw new EncryptException(e.getMessage());   
  28.         }   
  29.     }   
  30.     
  31.     /**  
  32.      *   * 生成公钥  
  33.      *   * @param modulus  
  34.      *   * @param publicExponent  
  35.      *   * @return RSAPublicKey  
  36.      *   * @throws EncryptException  
  37.      */  
  38.     public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws EncryptException {   
  39.         KeyFactory keyFac = null;   
  40.         try {   
  41.             keyFac = KeyFactory.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  42.         } catch (NoSuchAlgorithmException ex) {   
  43.             throw new EncryptException(ex.getMessage());   
  44.         }   
  45.     
  46.         RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));   
  47.         try {   
  48.             return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);   
  49.         } catch (InvalidKeySpecException ex) {   
  50.             throw new EncryptException(ex.getMessage());   
  51.         }   
  52.     }   
  53.     
  54.     /**  
  55.      *   * 生成私钥  
  56.      *   * @param modulus  
  57.      *   * @param privateExponent  
  58.      *   * @return RSAPrivateKey  
  59.      *   * @throws EncryptException  
  60.      */  
  61.     public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws EncryptException {   
  62.         KeyFactory keyFac = null;   
  63.         try {   
  64.             keyFac = KeyFactory.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  65.         } catch (NoSuchAlgorithmException ex) {   
  66.             throw new EncryptException(ex.getMessage());   
  67.         }   
  68.     
  69.         RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));   
  70.         try {   
  71.             return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);   
  72.         } catch (InvalidKeySpecException ex) {   
  73.             throw new EncryptException(ex.getMessage());   
  74.         }   
  75.     }   
  76.     
  77.     /**  
  78.      *   * 加密  
  79.      *   * @param key 加密的密钥  
  80.      *   * @param data 待加密的明文数据  
  81.      *   * @return 加密后的数据  
  82.      *   * @throws EncryptException  
  83.      */  
  84.     public static byte[] encrypt(Key key, byte[] data) throws EncryptException {   
  85.         try {   
  86.             Cipher cipher = Cipher.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  87.             cipher.init(Cipher.ENCRYPT_MODE, key);   
  88.             int blockSize = cipher.getBlockSize();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;因此共有2个加密块,第一个127 byte第二个为1个byte   
  89.             int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小   
  90.             int leavedSize = data.length % blockSize;   
  91.             int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;   
  92.             byte[] raw = new byte[outputSize * blocksSize];   
  93.             int i = 0;   
  94.             while (data.length - i * blockSize > 0) {   
  95.                 if (data.length - i * blockSize > blockSize)   
  96.                     cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);   
  97.                 else  
  98.                     cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);   
  99. //这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。   
  100.     
  101.                 i++;   
  102.             }   
  103.             return raw;   
  104.         } catch (Exception e) {   
  105.             throw new EncryptException(e.getMessage());   
  106.         }   
  107.     }   
  108.     
  109.     
  110.     
  111.     /**  
  112.      *   * 解密  
  113.      *   * @param key 解密的密钥  
  114.      *   * @param raw 已经加密的数据  
  115.      *   * @return 解密后的明文  
  116.      *   * @throws EncryptException  
  117.      */  
  118.     public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {   
  119.         try {   
  120.             Cipher cipher = Cipher.getInstance("RSA"new org.bouncycastle.jce.provider.BouncyCastleProvider());   
  121.             cipher.init(cipher.DECRYPT_MODE, key);   
  122.             int blockSize = cipher.getBlockSize();   
  123.             ByteArrayOutputStream bout = new ByteArrayOutputStream(64);   
  124.             int j = 0;   
  125.     
  126.             while (raw.length - j * blockSize > 0) {   
  127.                 bout.write(cipher.doFinal(raw, j * blockSize, blockSize));   
  128.                 j++;   
  129.             }   
  130.             return bout.toByteArray();   
  131.         } catch (Exception e) {   
  132.             throw new EncryptException(e.getMessage());   
  133.         }   
  134.     }   
  135.     
  136.     public static String byte2hex(byte[] b) {   
  137.         String hs = "";   
  138.         String stmp = "";   
  139.         for (int i = 0; i < b.length; i++) {   
  140.             stmp = Integer.toHexString(b[i] & 0xFF);   
  141.             if (stmp.length() == 1) {   
  142.                 hs += "0" + stmp;   
  143.             } else {   
  144.                 hs += stmp;   
  145.             }   
  146.         }   
  147.         //return hs;   
  148.         return hs.toUpperCase();   
  149.     }   
  150.     
  151.     
  152.     public static byte[] hex2byte(String hex) throws IllegalArgumentException {   
  153.         if (hex.length() % 2 != 0) {   
  154.             throw new IllegalArgumentException();   
  155.         }   
  156.         char[] arr = hex.toCharArray();   
  157.         byte[] b = new byte[hex.length() / 2];   
  158.         for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {   <
    分享到:
    评论

相关推荐

Global site tag (gtag.js) - Google Analytics