通常金融類的產品,涉及前端和後端交互的時候,都會都嚴格的數據安全保證。防止黑客攻擊,信息篡改。前端
加密方式有不少,總的來講,分爲2種:對稱和非對稱。咱們先來看一下,這兩種加密方式分別是什麼?他們有什麼區別?算法
對稱加密,即採用對稱的密碼編碼技術,他的特色是,加密和解密使用相同的祕鑰。json
常見的對稱加密算法有DES、3DES、Blowfish、IDEA、RC四、RC五、RC6和AES。對稱加密算法使用起來簡單快捷,密鑰較短,且破譯困難。後端
可是對稱祕鑰在使用過程當中存在如下問題:數組
一、對稱加密算法通常不能提供信息完整性的鑑別。它沒法驗證發送者和接受者的身份;安全
二、對稱密鑰的管理和分發工做是一件具備潛在危險的和煩瑣的過程。如何防止祕鑰泄露是一個難點。app
非對稱加密技術,須要兩個祕鑰,公鑰和私鑰。公鑰和私鑰成對出現。dom
若是用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;若是用私有密鑰對數據進行加密,那麼只有用對應的公開密鑰才能解密。由於加密和解密使用的是兩個不一樣的密鑰,因此這種算法叫做非對稱加密算法。ide
非對稱加密算法實現機密信息交換的基本過程是:甲方生成一對密鑰並將其中的一把做爲公用密鑰向其它方公開;獲得該公用密鑰的乙方使用該密鑰對機密信息進行加密後再發送給甲方;甲方再用本身保存的另外一把專用密鑰對加密後的信息進行解密。甲方只能用其專用密鑰解密由其公用密鑰加密後的任何信息。工具
非對稱加密的典型應用是數字簽名。
常見的非對稱加密算法有:RSA、ECC(移動設備用)、Diffie-Hellman、El Gamal、DSA(數字簽名用)。
如今,咱們已經對對稱和非對稱加密有了必定的瞭解。接下來,我將會給你們介紹一下,我在項目中使用的一種加密方式:對稱+非對稱。
先看一張流程圖:
先看發送方:
這裏,咱們主要有2步操做。
一、報文原文使用對稱加密技術。對稱加密的祕鑰(避免混淆,這裏稱對稱密碼)。根據隨機數生成。每次發起請求時,會從新產生一個隨機數,進一步下降被破解的風險。
二、對稱密碼經過非對稱加密方式進行加密。公鑰由後臺產生,匹配的私鑰由後臺保管。這樣產生一個加密後的對稱密碼。前端在發送給後端以後,後端須要用匹配的私鑰才能解開。
再看接收方:
接收方在接收到數據包以後,一樣有兩步操做:
一、會使用匹配的私鑰解密加密的對稱密碼,獲取到真實的對稱密碼。
二、使用對稱密碼,解密加密報文,獲取原報文內容。
這樣作的好處是:
一、由於咱們的對稱密碼是使用非對稱加密的,所以,想要破解,須要找到相應的公鑰才行。
二、每次請求會從新生成一個對稱密碼,這就加大了破解的難度。
public class RSA1 { /** * 隨機生成公鑰和私鑰 */ public static final String publicKeyString = "publicKeyString"; public static final String privateKeyString = "privateKeyString"; public static HashMap<String, String> getRandomKey() throws NoSuchAlgorithmException, InvalidKeySpecException { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); keyPairGen.initialize(1024);//生成大小 1024 KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//獲取公鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//獲取私鑰 HashMap<String, String> keyMap = new HashMap<String, String>(); keyMap.put(publicKeyString, new String(Base64.encode(publicKey.getEncoded(), Base64.DEFAULT)));//獲取公鑰Base64編碼 keyMap.put(privateKeyString, new String(Base64.encode(privateKey.getEncoded(), Base64.DEFAULT)));//獲取密鑰Base64編碼 return keyMap; } /** * 經過字符串生成私鑰 */ public static PrivateKey getPrivateKey(String privateKeyData) { PrivateKey privateKey = null; try { byte[] decodeKey = Base64.decode(privateKeyData, Base64.DEFAULT); //將字符串Base64解碼 PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(decodeKey);//建立x509證書封裝類 KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定RSA privateKey = keyFactory.generatePrivate(x509);//生成私鑰 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return privateKey; } /** * 經過字符串生成公鑰 */ public static PublicKey getPublicKey(String publicKeyData) { PublicKey publicKey = null; try { byte[] decodeKey = Base64.decode(publicKeyData, Base64.DEFAULT); X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); publicKey = keyFactory.generatePublic(x509); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return publicKey; } /** * 加密 */ public static byte[] encrypt(String data, Key key) { try { //取公鑰 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm(),"BC"); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(data.getBytes()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 解密 */ public static byte[] decrypt(byte[] data, Key key) { try { Cipher cipher = Cipher.getInstance("RSA","BC"); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return null; } }
public class AES_2 { public static byte[] genPrivateKey(String password) throws NoSuchAlgorithmException { KeyGenerator kgen = KeyGenerator.getInstance("AES"); byte[] bytes = tohash256Deal(password); SecureRandom securerandom = new SecureRandom(bytes); kgen.init(128, securerandom); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); return key.getEncoded(); } public static byte[] encrypt(String content, SecretKeySpec key) { try { //建立一個實現指定轉換的 Cipher對象,該轉換由指定的提供程序提供。 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] byteContent = content.getBytes("utf-8"); byte[] cryptograph = cipher.doFinal(byteContent); return Base64.encode(cryptograph, Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return null; } public static String decrypt(byte[] cryptograph, SecretKeySpec key) { try { Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] content = cipher.doFinal(Base64.decode(cryptograph, Base64.DEFAULT)); return new String(content); } catch (Exception e) { e.printStackTrace(); } return null; } public static byte[] encrypt(String content, String password) { try { //"AES":請求的密鑰算法的標準名稱 KeyGenerator kgen = KeyGenerator.getInstance("AES"); //256:密鑰生成參數;securerandom:密鑰生成器的隨機源 SecureRandom securerandom = new SecureRandom(tohash256Deal(password)); kgen.init(128, securerandom); //生成祕密(對稱)密鑰 SecretKey secretKey = kgen.generateKey(); //返回基本編碼格式的密鑰 byte[] enCodeFormat = secretKey.getEncoded(); //根據給定的字節數組構造一個密鑰。enCodeFormat:密鑰內容;"AES":與給定的密鑰內容相關聯的密鑰算法的名稱 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); //將提供程序添加到下一個可用位置 Security.addProvider(new BouncyCastleProvider()); //建立一個實現指定轉換的 Cipher對象,該轉換由指定的提供程序提供。 //"AES/ECB/PKCS7Padding":轉換的名稱;"BC":提供程序的名稱 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] byteContent = content.getBytes("utf-8"); byte[] cryptograph = cipher.doFinal(byteContent); return Base64.encode(cryptograph, Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return null; } public static String decrypt(byte[] cryptograph, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom securerandom = new SecureRandom(tohash256Deal(password)); kgen.init(128, securerandom); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] content = cipher.doFinal(Base64.decode(cryptograph, Base64.DEFAULT)); return new String(content); } catch (Exception e) { e.printStackTrace(); } return null; } public static String parseByte2HexStr(byte buf[]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length; i++) { String hex = Integer.toHexString(buf[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } public static byte[] parseHexStr2Byte(String hexStr) { if (hexStr.length() < 1) return null; byte[] result = new byte[hexStr.length() / 2]; for (int i = 0; i < hexStr.length() / 2; i++) { int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); result[i] = (byte) (high * 16 + low); } return result; } public static byte[] tohash256Deal(String datastr) { try { MessageDigest digester = MessageDigest.getInstance("SHA-256"); digester.update(datastr.getBytes()); byte[] hex = digester.digest(); return hex; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.getMessage()); } } }
發送方和接收方的實現:
String content = "000"; JSONObject jsonObject = new JSONObject(); try { LogT.i("++++++++++++++++++++++發送方+++++++++++++++++++++++++="); //產生私鑰 int random = (int) ((Math.random() * 9 + 1) * 100000); //私鑰字節 byte[] bytes = AES_2.genPrivateKey(String.valueOf(random)); //傳輸報文加密 SecretKeySpec key1 = new SecretKeySpec(bytes, "AES"); byte[] content_encrypt = AES_2.encrypt(content, key1); //公鑰對私鑰加密 PublicKey publicKey = RSA1.getPublicKey(public_key); sKey_encrypt = RSA1.encrypt(Base64.encodeToString(bytes, Base64.DEFAULT), publicKey); //數據組裝 jsonObject.put("key", Base64.encodeToString(sKey_encrypt, Base64.DEFAULT)); jsonObject.put("content", AES_2.parseByte2HexStr(content_encrypt)); LogT.i("+++++++++++++++++++++++接收方++++++++++++++++++++++++="); //解析獲取私鑰 PrivateKey privateKey = RSA1.getPrivateKey(private_key); //解析接收到的key數據 byte[] decode = Base64.decode(Base64.encodeToString(sKey_encrypt, Base64.DEFAULT), Base64.DEFAULT); //私鑰解密 byte[] decrypt = RSA1.decrypt(decode, privateKey); //解碼私鑰字節 byte[] decode_orig = Base64.decode(new String(decrypt), Base64.DEFAULT); //加密的報文 byte[] HexStrByte = AES_2.parseHexStr2Byte(AES_2.parseByte2HexStr(content_encrypt)); SecretKeySpec key2 = new SecretKeySpec(decode_orig, "AES"); //解密後的報文 String decrypt1 = AES_2.decrypt(HexStrByte, key2); LogT.i(decrypt1);//000 } catch (Exception e) { e.printStackTrace(); }
原文:https://blog.csdn.net/Aminy123/article/details/81871092