1. 程式人生 > 實用技巧 >加密與解密

加密與解密

對稱加密與非對稱加密

對稱加密:加密和解密使用同一個祕鑰,被黑客攔截不安全。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     }