对称加密与非对称加密
对称加密:加密和解密使用同一个秘钥,被黑客拦截不安全。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 }