1. 程式人生 > >非對稱加密演算法RSA工具

非對稱加密演算法RSA工具

非對稱加密演算法RSA工具

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.
spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.bouncycastle.util.encoders.Base64; public class RSAUtil
{ /** * RSA演算法 */ private static final String KEY_ALGORITHM = "RSA"; /** * 數字簽名 */ private static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; public static String[] createKeys() { try { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); String[] res = new String[2]; res[0] = byteArrayToBase64Str(publicKey.getEncoded()); res[1] = byteArrayToBase64Str(privateKey.getEncoded()); return res; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } private static byte[] base64StrToByteArray(String data) { return Base64.decode(data.getBytes()); } private static String byteArrayToBase64Str(byte[] data) { return Base64.toBase64String(data); } /** * 數字簽名 * * @param data 要簽名的密文 * @param privateKey 私鑰 * @return 返回簽名信息 */ public static String RSASign(String data, String privateKey) { try { // 解密由base64編碼的私鑰 byte[] keyBytes = base64StrToByteArray(privateKey); // 構造PKCS8EncodedKeySpec物件 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密演算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私鑰匙物件 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私鑰對資訊生成數字簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(base64StrToByteArray(data)); return byteArrayToBase64Str(signature.sign()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } return null; } /** * 驗證簽名 * * @param data 要驗證的密文 * @param publicKey 公鑰 * @param sign 簽名信息 * @return 返回驗證成功狀態 */ public static boolean RSAVerify(String data, String publicKey, String sign) { try { // 解密由base64編碼的公鑰 byte[] keyBytes = base64StrToByteArray(publicKey); // 構造X509EncodedKeySpec物件 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密演算法 Signature signature; KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公鑰匙物件 PublicKey pubKey = keyFactory.generatePublic(keySpec); signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(base64StrToByteArray(data)); // 驗證簽名是否正常 return signature.verify(base64StrToByteArray(sign)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } return false; } /** * 私鑰解密 * * @param data 要解密的字串 * @param key 私鑰 * @return 返回解密後的字串 */ public static String RSADecryptByPrivateKey(String data, String key) { try { // 對金鑰解密 byte[] keyBytes = base64StrToByteArray(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對資料解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] encryptedData = base64StrToByteArray(data); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 對資料分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 公鑰解密 * * @param data 要解密的資料 * @param key 公鑰 * @return 返回解密後的資料 */ public static String RSADecryptByPublicKey(String data, String key) { try { // 對金鑰解密 byte[] keyBytes = base64StrToByteArray(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對資料解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] encryptedData = base64StrToByteArray(data); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 對資料分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 公鑰加密 * * @param data 要加密的資料 * @param key 公鑰 * @return 返回加密的資料 */ public static String RSAEncryptByPublicKey(String data, String key) { try { // 對公鑰解密 byte[] keyBytes = base64StrToByteArray(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對資料加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] decryptedData = data.getBytes(); int inputLen = decryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 對資料分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(decryptedData, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(decryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return byteArrayToBase64Str(encryptedData); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 私鑰加密 * * @param data 要加密的資料 * @param key 私鑰 * @return 返回加密後的資料 */ public static String RSAEncryptByPrivateKey(String data, String key) { try { // 對金鑰解密 byte[] keyBytes = base64StrToByteArray(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對資料加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] decryptedData = data.getBytes(); int inputLen = decryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 對資料分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(decryptedData, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(decryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return byteArrayToBase64Str(encryptedData); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace