package com.ab.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; 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.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; public class AbRsa { private static final String ALGORITHM = "RSA"; public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; /** * 随机生成RSA密钥对 * @param keyLength 密钥长度,范围:512~2048 一般1024 * @return */ public static KeyPair generateRSAKeyPair(int keyLength){ try{ KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM); kpg.initialize(keyLength); return kpg.genKeyPair(); } catch (NoSuchAlgorithmException e){ e.printStackTrace(); return null; } } /** * * RSA 公钥加密. * 用公钥对一个字串进行加密然后用私钥解密,是RSA加密,只能加密少量数据.一般是用来加密会话密钥 * @param content 内容 * @param publicKey 公钥 * @return 加密的内容(待发送) */ public static String encrypt(String content, String publicKey) { try { PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, publicKey); return encrypt(content,pubkey); } catch (Exception e) { e.printStackTrace(); return null; } } /** * * RSA 公钥加密. * 用公钥对一个字串进行加密然后用私钥解密,是RSA加密,只能加密少量数据.一般是用来加密会话密钥 * @param content 内容 * @param publicKey 公钥 * @return 加密的内容(待发送) */ public static String encrypt(String content, PublicKey publicKey) { try { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte plaintext[] = content.getBytes("UTF-8"); byte[] output = cipher.doFinal(plaintext); String s = new String(AbBase64.encode(output)); return s; } catch (Exception e) { e.printStackTrace(); return null; } } /** * * RSA 用私钥解密. * @param encryptString * @param privateKey * @return */ public byte[] decrypt(String encryptString, String privateKey) { try { byte[] encryptByte = AbBase64.decode(encryptString); PrivateKey prikey = getPrivateKeyFromX509(ALGORITHM, privateKey); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, prikey); return cipher.doFinal(encryptByte); } catch (Exception e) { e.printStackTrace(); } return null; } /** * * RSA 用私钥解密. * @param encryptString * @param privateKey * @return */ public byte[] decrypt(String encryptString, PrivateKey privateKey) { try { byte[] encryptByte = AbBase64.decode(encryptString); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(encryptByte); } catch (Exception e) { e.printStackTrace(); } return null; } /** * * 获取数字签名. * 利用私钥对一个字串进行加密,得到数字签名.是用来证明信息的确来自密钥所有人.然后用公钥解密。 * @param content 内容 * @param privateKey 私钥 * @return 数字签名 */ public static String sign(String content, String privateKey) { String charset = "utf-8"; try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( AbBase64.decode(privateKey)); KeyFactory keyf = KeyFactory.getInstance(ALGORITHM); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update(content.getBytes(charset)); byte[] signed = signature.sign(); return AbBase64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } /** * * 验证 * @param content 内容 * @param sign 签名 * @param publicKey 公钥 * @return */ public static boolean doCheck(String content, String sign, String publicKey) { try { KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); byte[] encodedKey = AbBase64.decode(publicKey); PublicKey pubKey = keyFactory .generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update(content.getBytes("utf-8")); boolean bverify = signature.verify(AbBase64.decode(sign)); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } /** * * 生成公钥. * @param algorithm * @param bysKey * @return * @throws NoSuchAlgorithmException * @throws Exception */ private static PublicKey getPublicKeyFromX509(String algorithm, String bysKey) throws NoSuchAlgorithmException, Exception { byte[] decodedKey = AbBase64.decode(bysKey); X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey); KeyFactory keyFactory = KeyFactory.getInstance(algorithm); return keyFactory.generatePublic(x509); } /** * * 生成私钥. * @param algorithm * @param bysKey * @return * @throws NoSuchAlgorithmException * @throws Exception */ private static PrivateKey getPrivateKeyFromX509(String algorithm, String bysKey) throws NoSuchAlgorithmException, Exception { byte[] decodedKey = AbBase64.decode(bysKey); X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey); KeyFactory keyFactory = KeyFactory.getInstance(algorithm); return keyFactory.generatePrivate(x509); } /** * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法 * * @param keyBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException{ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 通过私钥byte[]将公钥还原,适用于RSA算法 * * @param keyBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException{ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 使用N、e值还原公钥 * * @param modulus * @param publicExponent * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PublicKey getPublicKey(String modulus, String publicExponent) throws NoSuchAlgorithmException, InvalidKeySpecException{ BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(publicExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 使用N、d值还原私钥 * * @param modulus * @param privateExponent * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PrivateKey getPrivateKey(String modulus, String privateExponent) throws NoSuchAlgorithmException, InvalidKeySpecException{ BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(privateExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 从字符串中加载公钥 * * @param publicKeyStr * 公钥数据字符串 * @throws Exception * 加载公钥时产生的异常 */ public static PublicKey loadPublicKey(String publicKey) throws Exception{ try { byte[] buffer = AbBase64.decode(publicKey); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e){ throw new Exception("无此算法"); } catch (InvalidKeySpecException e){ throw new Exception("公钥非法"); } catch (NullPointerException e){ throw new Exception("公钥数据为空"); } } /** * 从字符串中加载私钥 * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。 * * @param privateKey * @return * @throws Exception */ public static PrivateKey loadPrivateKey(String privateKey) throws Exception{ try{ byte[] buffer = AbBase64.decode(privateKey); // X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException e){ throw new Exception("无此算法"); } catch (InvalidKeySpecException e){ throw new Exception("私钥非法"); } catch (NullPointerException e){ throw new Exception("私钥数据为空"); } } /** * 从文件中输入流中加载公钥 * * @param in * 公钥输入流 * @throws Exception * 加载公钥时产生的异常 */ public static PublicKey loadPublicKey(InputStream in) throws Exception{ try{ return loadPublicKey(readKey(in)); } catch (IOException e){ throw new Exception("公钥数据流读取错误"); } catch (NullPointerException e){ throw new Exception("公钥输入流为空"); } } /** * 从文件中加载私钥 * * @param keyFileName * 私钥文件名 * @return 是否成功 * @throws Exception */ public static PrivateKey loadPrivateKey(InputStream in) throws Exception{ try { return loadPrivateKey(readKey(in)); } catch (IOException e) { throw new Exception("私钥数据读取错误"); } catch (NullPointerException e){ throw new Exception("私钥输入流为空"); } } /** * 读取密钥信息 * * @param in * @return * @throws IOException */ private static String readKey(InputStream in) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(in)); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { if (readLine.charAt(0) == '-'){ continue; } else{ sb.append(readLine); sb.append(' '); } } return sb.toString(); } /** * 打印公钥信息 * * @param publicKey */ public static void printPublicKeyInfo(PublicKey publicKey){ RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey; System.out.println("----------RSAPublicKey----------"); System.out.println("Modulus.length=" + rsaPublicKey.getModulus().bitLength()); System.out.println("Modulus=" + rsaPublicKey.getModulus().toString()); System.out.println("PublicExponent.length=" + rsaPublicKey.getPublicExponent().bitLength()); System.out.println("PublicExponent=" + rsaPublicKey.getPublicExponent().toString()); } public static void printPrivateKeyInfo(PrivateKey privateKey){ RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey; System.out.println("----------RSAPrivateKey ----------"); System.out.println("Modulus.length=" + rsaPrivateKey.getModulus().bitLength()); System.out.println("Modulus=" + rsaPrivateKey.getModulus().toString()); System.out.println("PrivateExponent.length=" + rsaPrivateKey.getPrivateExponent().bitLength()); System.out.println("PrivatecExponent=" + rsaPrivateKey.getPrivateExponent().toString()); } }