加密與解密
阿新 • • 發佈:2020-12-09
對稱加密與非對稱加密
對稱加密:加密和解密使用同一個祕鑰,被黑客攔截不安全。DES,AES,3DES等等
非對稱加密:加密和解密使用不同的祕鑰,一把作為公開的公鑰,另一把作為私鑰。公鑰加密的資訊,只有私鑰才能解密。私鑰加密的資訊,只有公鑰才能解密。非常安全,黑客攔截也沒用,因為私鑰未公開。RSA,ECC等。
兩者在C/S模型的用法通常是:
1. 服務端計算出一對祕鑰pub/pri。將私鑰保密,將公鑰公開。
2. 客戶端請求服務端時,拿到服務端的公鑰pub。
3. 客戶端通過AES計算出一個對稱加密的祕鑰X(更安全的是用非對稱加密的公鑰)。 然後使用pub將X進行加密。
4. 客戶端將加密後的密文傳送給服務端。服務端通過pri解密獲得X。
5. 然後兩邊的通訊內容就通過對稱金鑰X以對稱加密演算法來加解密。
RSA生成祕鑰對
1 public static Map<String, String> genKeyPair() { 2 // KeyPairGenerator類用於生成公鑰和私鑰對,基於RSA演算法生成物件 3 KeyPairGenerator keyPairGen; 4 try { 5 keyPairGen = KeyPairGenerator.getInstance(RSA_ALGORITHM); 6 //初始化金鑰對生成器,金鑰大小為96-1024位 7 keyPairGen.initialize(1024, new SecureRandom()); 8 // 生成一個金鑰對,儲存在keyPair中 9 KeyPair keyPair = keyPairGen.generateKeyPair(); 10 // 得到私鑰 11 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 12 //得到公鑰 13 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); 14 String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded())); 15 // 得到私鑰字串 16 String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded()))); 17 // 將公鑰和私鑰儲存到Map 18 Map<String, String> keyMap = new HashMap<>(); 19 keyMap.put("public", publicKeyString); 20 keyMap.put("private", privateKeyString); 21 return keyMap; 22 } catch (NoSuchAlgorithmException e) { 23 logger.error("無此演算法", e); 24 throw new PcAuthException(ExceptionEnum.ENCRYPTION_EXCEPTION); 25 } 26 }
RSA加密和解密
1 public static String encrypt(String str, String publicKey) throws Exception { 2 // base64編碼的公鑰 3 byte[] decoded = Base64.decodeBase64(publicKey); 4 RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(“RSA”) 5 .generatePublic(new X509EncodedKeySpec(decoded)); 6 // RSA加密 7 Cipher cipher = Cipher.getInstance("RSA"); 8 cipher.init(Cipher.ENCRYPT_MODE, pubKey); 9 return Base64.encodeBase64String(cipher.doFinal(str.getBytes(CHARSET))); 10 }
1 public static String decrypt(String str, String privateKey) { 2 // 64位解碼加密後的字串 3 byte[] inputByte = new byte[0]; 4 try { 5 inputByte = Base64.decodeBase64(str.getBytes(CHARSET)); 6 } catch (UnsupportedEncodingException e) { 7 logger.error(e.getMessage()); 8 throw new PcAuthException(ExceptionEnum.ENCRYPTION_EXCEPTION); 9 } 10 // base64編碼的私鑰 11 byte[] decoded = Base64.decodeBase64(privateKey); 12 RSAPrivateKey priKey = null; 13 try { 14 priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA") 15 .generatePrivate(new PKCS8EncodedKeySpec(decoded)); 16 } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 17 logger.error(e.getMessage()); 18 throw new PcAuthException(ExceptionEnum.ENCRYPTION_EXCEPTION); 19 } 20 // RSA解密 21 Cipher cipher = null; 22 try { 23 cipher = Cipher.getInstance(“RSA"); 24 } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 25 logger.error(e.getMessage()); 26 throw new PcAuthException(ExceptionEnum.ENCRYPTION_EXCEPTION); 27 } 28 try { 29 cipher.init(Cipher.DECRYPT_MODE, priKey); 30 } catch (InvalidKeyException e) { 31 logger.error(e.getMessage()); 32 throw new PcAuthException(ExceptionEnum.ENCRYPTION_EXCEPTION); 33 } 34 try { 35 return new String(cipher.doFinal(inputByte)); 36 } catch (IllegalBlockSizeException | BadPaddingException e) { 37 logger.error(e.getMessage()); 38 throw new PcAuthException(ExceptionEnum.ENCRYPTION_EXCEPTION); 39 } 40 }