本文源碼:GitHub·點這裏 || GitEE·點這裏java
RSA加密是一種非對稱加密,在公開密鑰加密和電子商業中RSA被普遍使用。能夠在不直接傳遞密鑰的狀況下,完成加解密操做。這可以確保信息的安全性,避免了直接傳遞密鑰所形成的被破解的風險。是由一對密鑰來進行加解密的過程,分別稱爲公鑰和私鑰。該加密算法的原理就是對一極大整數作因數分解的困難性來保證安全性。
數字簽名就是信息的來源添加一段沒法被僞造的加密字符串,這段數字串做爲對信息的來源真實性的一個有效證實。這個過程稱爲簽名和驗籤。
(1)、乙方生成一對密鑰即公鑰和私鑰,私鑰不公開,乙方本身持有,公鑰爲公開,甲方持有。git
(2)、乙方收到甲方加密的消息,使用私鑰對消息進行解密,獲取明文。github
(1)、乙方收到消息後,須要回覆甲方,用私鑰對回覆消息簽名,並將消息明文和消息簽名回覆甲方。算法
(2)、甲方收到消息後,使用公鑰進行驗籤,若是驗簽結果是正確的,則證實消息是乙方回覆的。segmentfault
private static HashMap<String, String> getTheKeys() { HashMap<String, String> keyPairMap = new HashMap<String, String>(); KeyPairGenerator keyPairGen = null; try { keyPairGen = KeyPairGenerator.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 密鑰大小:1024 位 keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); String publicKey = printBase64Binary(keyPair.getPublic().getEncoded()); String privateKey = printBase64Binary(keyPair.getPrivate().getEncoded()); keyPairMap.put("publicKey", publicKey); keyPairMap.put("privateKey", privateKey); return keyPairMap ; }
文件位置數組
public static final String PUB_KEY = "rsaKey/public.key" ; public static final String PRI_KEY = "rsaKey/private.key" ;
文件加載安全
public static String getKey (String keyPlace) throws Exception { BufferedReader br= null; try { br= new BufferedReader(new InputStreamReader(RsaCryptUtil.class.getClassLoader(). getResourceAsStream(keyPlace))); String readLine= null; StringBuilder keyValue = new StringBuilder(); while((readLine= br.readLine())!=null){ if(!(readLine.charAt(0)=='-')){ keyValue.append(readLine); } } return keyValue.toString(); } catch (Exception e) { throw new Exception("RSA密鑰讀取錯誤",e) ; } finally{ if (br != null) { try { br.close(); } catch (Exception e) { System.out.println("密鑰讀取流關閉異常"); } } } }
public static RSAPublicKey createPublicKey(String publicKeyValue) throws Exception { try { byte[] buffer = DatatypeConverter.parseBase64Binary(publicKeyValue); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (Exception e) { throw new Exception("公鑰建立失敗", e); } }
public static RSAPrivateKey createPrivateKey(String privateKeyValue) throws Exception { try { byte[] buffer = javax.xml.bind.DatatypeConverter.parseBase64Binary(privateKeyValue); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (Exception e) { throw new Exception("私鑰建立失敗", e); } }
public static String encrypt(RSAPublicKey publicKey, byte[] clearData) throws Exception { if (publicKey == null) { throw new Exception("加密公鑰爲空, 沒法加密"); } try { Cipher cipher = Cipher.getInstance("RSA") ; cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] output = cipher.doFinal(clearData); return printBase64Binary(output); } catch (Exception e) { throw new Exception("公鑰加密失敗",e); } }
public static String decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception { if (privateKey == null) { throw new Exception("解密私鑰爲空, 沒法解密"); } try { Cipher cipher = Cipher.getInstance("RSA") ; cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] output = cipher.doFinal(cipherData); return new String(output); } catch (BadPaddingException e) { throw new Exception("私鑰解密失敗",e); } }
public static String sign (String signData, PrivateKey privateKey) throws Exception { byte[] keyBytes = privateKey.getEncoded(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey key = keyFactory.generatePrivate(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(key); signature.update(signData.getBytes()); return printBase64Binary(signature.sign()); }
public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception { byte[] keyBytes = publicKey.getEncoded(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(key); signature.update(srcData.getBytes()); return signature.verify(parseBase64Binary(sign)); }
/** * 字節數組轉字符 */ public static String printBase64Binary(byte[] bytes) { return DatatypeConverter.printBase64Binary(bytes); } /** * 字符轉字節數組 */ public static byte[] parseBase64Binary(String value) { return DatatypeConverter.parseBase64Binary(value); }
public static void testCreateKey () throws Exception { HashMap<String, String> map = RsaCryptUtil.getTheKeys(); String privateKeyStr=map.get("privateKey"); String publicKeyStr=map.get("publicKey"); System.out.println("私鑰:"+privateKeyStr); System.out.println("公鑰:"+publicKeyStr); //消息發送方 String originData="cicada-smile"; System.out.println("原文:"+originData); String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr), originData.getBytes()); System.out.println("加密:"+encryptData); //消息接收方 String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr), RsaCryptUtil.parseBase64Binary(encryptData)); System.out.println("解密:"+decryptData); }
public static void testReadKey () throws Exception { String value = getKey("rsaKey/public.key"); System.out.println(value); String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ; String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ; //消息發送方 String originData="cicada-smile"; System.out.println("原文:"+originData); String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr), originData.getBytes()); System.out.println("加密:"+encryptData); //消息接收方 String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr), RsaCryptUtil.parseBase64Binary(encryptData)); System.out.println("解密:"+decryptData); }
public static void testSignVerify () throws Exception { String signData = "cicada-smile" ; String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ; String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ; String signValue = sign(signData,RsaCryptUtil.createPrivateKey(privateKeyStr)) ; boolean flag = verify(signData,RsaCryptUtil.createPublicKey(publicKeyStr),signValue); System.out.println("原文:"+signData); System.out.println("簽名:"+signValue); System.out.println("驗籤:"+flag); }
GitHub·地址 https://github.com/cicadasmile GitEE·地址 https://gitee.com/cicadasmile