Java生鮮電商平臺-APP/小程序接口傳輸常見的加密算法及詳解java
說明:Java生鮮電商平臺-APP/小程序接口傳輸常見的加密算法及詳解,加密算法,是如今每一個軟件項目裏必須用到的內容。算法
普遍應用在包括了用戶登入、數字簽名、數據傳輸等多個場合。今天我把常見的加密算法所有整理在這裏,供你們學習參考。小程序
首先,你們要知道加密算法能幹什麼,利用加密算法來對數據通訊的過程進行加密傳輸是一種最多見的安全手段。利用該手段可以達到一下三個目的:安全
一、數據保密性,防止用戶數據被竊取或泄露;
二、數據完整性,防止用戶傳輸的數據被篡改;
三、通訊雙方身份確認,確保數據來源合法;函數
各類加密算法對好比下:學習
1,單向散列加密算法:
2,對稱加密算法:
3,非對稱加密算法:
加密算法詳解編碼
一,單向散列加密加密
單向散列加密算法經常使用於提取數據,驗證數據的完整性。發送者將明文經過單向加密算法加密生成定長的密文串,而後將明文和密文串傳遞給接收方。接收方在收到報文後,將解明文使用相同的單向加密算法進行加密,得出加密後的密文串。隨後與發送者發送過來的密文串進行對比,若發送前和發送後的密文串相一致,則說明傳輸過程當中數據沒有損壞;若不一致,說明傳輸過程當中數據丟失了。其次也用於密碼加密傳遞存儲。單向加密算法只能用於對數據的加密,沒法被解密,其特色爲定長輸出、雪崩效應。3d
1.1,MD5加密算法
MD5加密算法用的是哈希函數,通常應用於對信息產生信息摘要,防止信息被篡改。最多見的使用是對密碼加密、生成數字簽名。從嚴格意義上來講,MD5是摘要算法,並不是加密算法。MD5 生成密文時,不管要加密的字符串有多長,它都會輸出長度爲 128bits 的一個密文串,一般16 進制時爲 32 個字符code
public static final byte[] computeMD5(byte[] content) { try { MessageDigest md5 = MessageDigest.getInstance("MD5"); return md5.digest(content); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
1.2,SHA1加密算法
SHA1加密算法,與MD5同樣,也是目前較流行的摘要算法。但SHA1 比 MD5 的 安全性更高。對長度小於 2 ^ 64 位的消息,SHA1會產生一個 160 位的 消息摘要。基於 MD五、SHA1 的信息摘要特性以及不可逆,能夠被應用在檢查文件完整性, 數字簽名等場景。
public static byte[] computeSHA1(byte[] content) { try { MessageDigest sha1 = MessageDigest.getInstance("SHA1"); return sha1.digest(content); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
1.3,SHA256加密算法
SHA256是SHA2算法中的一種,如SHA2加密算法中有:SHA24四、SHA25六、SHA512等。SHA2屬於SHA1的升級,SHA1是160位的哈希值,而SHA2是組合值,有不一樣的位數,其中最受歡迎的是256位(SHA256算法)。
SSL行業選擇SHA做爲數字簽名的散列算法,從2011到2015,一直以SHA-1位主導算法。但隨着互聯網技術的提高,SHA-1的缺點愈來愈突顯。從去年起,SHA-2成爲了新的標準,因此如今簽發的SSL證書,必須使用該算法簽名。
public static byte[] getSHA256(String str) { MessageDigest messageDigest; String encodestr = ""; try { messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(str.getBytes("UTF-8")); return messageDigest.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }
二,對稱加密算法
對稱加密算法採用單密鑰加密,在數據傳輸過程當中,發送方將原始數據分割成固定大小的塊,通過密鑰和加密算法逐個加密後,發送給接收方;接收方收到加密後的報文後,結合密鑰和解密算法解密組合後得出原始數據。因爲加解密算法是公開的,所以在這過程當中,密鑰的安全傳遞就成爲了相當重要的事了。而密鑰一般來講是經過雙方協商,以物理的方式傳遞給對方,或者利用第三方平臺傳遞給對方,一旦這過程出現了密鑰泄露,不懷好意的人就能結合相應的算法攔截解密出其加密傳輸的內容。
AES、DES、3DES 都是對稱的塊加密算法,加解密的過程是可逆的。
2.1,DES算法
DES算法爲密碼體制中的對稱密碼體制,又被稱爲美國數據加密標準,是1972年美國IBM公司研製的對稱密碼體制加密算法。明文按64位進行分組,密鑰長64位,密鑰事實上是56位參與DES運算(第八、1六、2四、3二、40、4八、5六、64位是校驗位, 使得每一個密鑰都有奇數個1)分組後的明文組和56位的密鑰按位替代或交換的方法造成密文組的加密方法。
DES 加密算法是對密鑰進行保密,公開加密和解密算。只有知道發送方相同密鑰的人才能解讀獲取的密文數據。想破譯 DES 加密算法,就要搜索密鑰的編碼。對於56位長度的密鑰來講,用窮舉法,其運算次數爲 2 ^ 56 次。
3DES又稱Triple DES,是DES加密算法的一種模式,它使用2條不一樣的56位的密鑰對數據進行三次加密。DES使用56位密鑰和密碼塊的方法,而在密碼塊的方法中,文本被分紅64位大小的文本塊而後再進行加密。比起最初的DES,3DES更爲安全。
public class Des3 { private static final String Algorithm = "DESede"; /** * 加密 * @param keybyte * @param src * @return */ public static byte[] encryptMode(byte[] keybyte, byte[] src) { try { // 生成密鑰 SecretKey deskey = new SecretKeySpec(keybyte, Algorithm); // 加密 Cipher c1 = Cipher.getInstance(Algorithm); c1.init(Cipher.ENCRYPT_MODE, deskey); return c1.doFinal(src); } catch (java.security.NoSuchAlgorithmException e1) { e1.printStackTrace(); } catch (javax.crypto.NoSuchPaddingException e2) { e2.printStackTrace(); } catch (java.lang.Exception e3) { e3.printStackTrace(); } return null; } /** * 解密 * @param keybyte 爲加密密鑰,長度爲24字節 * @param src 爲加密後的緩衝區 * @return */ public static byte[] decryptMode(byte[] keybyte, byte[] src) { try { // 生成密鑰 SecretKey deskey = new SecretKeySpec(keybyte, Algorithm); // 解密 Cipher c1 = Cipher.getInstance(Algorithm); c1.init(Cipher.DECRYPT_MODE, deskey); return c1.doFinal(src); } catch (Exception e) { e.printStackTrace(); } return null; } // 轉換成十六進制字符串 public static String byte2hex(byte[] b) { String hs = ""; String stmp = ""; for (int n = 0; n < b.length; n++) { stmp = (java.lang.Integer.toHexString(b[n] & 0XFF)); if (stmp.length() == 1) { hs = hs + "0" + stmp; } else { hs = hs + stmp; } if (n < b.length - 1) { hs = hs + ":"; } } return hs.toUpperCase(); } }
2.3,AES算法
AES算法是密碼學中的高級加密標準,同時也是美國聯邦政府採用的區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。算法採用對稱分組密碼體制,密鑰長度的最少支持爲 128 位、 192 位、256 位,分組長度 128 位,算法應易於各類硬件和軟件實現。AES自己就是爲了取代DES的,AES具備更好的安全性、效率和靈活性。
public class AESUtils { /** * 加密 * * @param content * @param strKey * @return * @throws Exception */ public static byte[] encrypt(String content, String strKey) throws Exception { SecretKeySpec skeySpec = getKey(strKey); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes()); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); return cipher.doFinal(content.getBytes()); } /** * 解密 * * @param strKey * @param content * @return * @throws Exception */ public static String decrypt(byte[] content, String strKey) throws Exception { SecretKeySpec skeySpec = getKey(strKey); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes()); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); byte[] original = cipher.doFinal(content); String originalString = new String(original); return originalString; } private static SecretKeySpec getKey(String strKey) throws Exception { byte[] arrBTmp = strKey.getBytes(); byte[] arrB = new byte[16]; for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) { arrB[i] = arrBTmp[i]; } SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES"); return skeySpec; } }
三,非對稱加密算法非對稱加密算法採用公鑰(publickey)和私鑰(privatekey)兩種不一樣的密鑰來進行加解密。公鑰與私鑰是一對,若是用公鑰對數據進行加密,只有用對應的私鑰才能解密,反之亦然。由於加密和解密使用的是兩個不一樣的密鑰,因此這種算法叫做非對稱加密算法。 非對稱加密算法實現機密信息交換的基本過程是:甲方生成一對密鑰並將公鑰公開,須要向甲方發送信息的其餘角色(乙方)使用該密鑰(甲方的公鑰)對機密信息進行加密後再發送給甲方;甲方再用本身私鑰對加密後的信息進行解密。甲方想要回復乙方時正好相反,使用乙方的公鑰對數據進行加密,同理,乙方使用本身的私鑰來進行解密。
3.1,RSA算法
RSA是目前最有影響力的公鑰加密算法,也是被廣泛認爲是目前最優秀的公鑰方案之一。RSA算法是第一個能同時用於加密和數字簽名的算法,也易於理解和操做。RSA是被研究得最普遍的公鑰算法,從提出到現今的三十多年裏,經歷了各類攻擊的考驗,逐漸爲人們接受,截止2017年被廣泛認爲是最優秀的公鑰方案之一。也已被ISO推薦爲公鑰數據加密標準。
public class RSAUtils { public static final String KEY_ALGORITHM = "RSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * 私鑰解密 * * @param data 已加密數據 * @param privateKey 私鑰(BASE64編碼) * @return * @throws Exception */ public static String decryptByPrivateKey(String data, String privateKey) throws Exception { byte[] keyBytes = Base64.decodeBase64(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); byte[] buff = cipher.doFinal(Base64.decodeBase64(data)); return new String(buff); } /** * 公鑰解密 * * @param data 已加密數據 * @param publicKey 公鑰(BASE64編碼) * @return * @throws Exception */ public static String decryptByPublicKey(String data, String publicKey) throws Exception { byte[] keyBytes = Base64.decodeBase64(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); // 執行解密操做 byte[] buff = cipher.doFinal(Base64.decodeBase64(data)); return new String(buff); } /** * 公鑰加密 * * @param data 源數據 * @param publicKey 公鑰(BASE64編碼) * @return * @throws Exception */ public static String encryptByPublicKey(String data, String publicKey) throws Exception { byte[] keyBytes = Base64.decodeBase64(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 對數據加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); byte[] buff = cipher.doFinal(data.getBytes()); return Base64.encodeBase64String(buff); } /** * 私鑰加密 * * @param data 源數據 * @param privateKey 私鑰(BASE64編碼) * @return * @throws Exception */ public static String encryptByPrivateKey(String data, String privateKey) throws Exception { byte[] keyBytes = Base64.decodeBase64(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); byte[] buff = cipher.doFinal(data.getBytes()); // 執行加密操做。加密後的結果一般都會用Base64編碼進行傳輸 return Base64.encodeBase64String(buff); } /** * 獲取私鑰 * * @param keyMap 密鑰對 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64.encodeBase64String(key.getEncoded()); } /** * 獲取公鑰 * * @param keyMap 密鑰對 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64.encodeBase64String(key.getEncoded()); } /** * 生成密鑰對(公鑰和私鑰) * * @return * @throws Exception */ public static Map<String, Object> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } }
ECC(橢圓加密算法)是一種公鑰加密體制,主要優點是在某些狀況下它比其餘的方法使用更小的密鑰——好比RSA加密算法——提供至關的或更高等級的安全。不過一個缺點是加密和解密操做的實現比其餘機制時間長。它相比RSA算法,對 CPU 消耗嚴重
public abstract class ECCCoder extends Coder { public static final String ALGORITHM = "EC"; private static final String PUBLIC_KEY = "ECCPublicKey"; private static final String PRIVATE_KEY = "ECCPrivateKey"; /** * 用私鑰解密 * @param data * @param key * @return * @throws Exception */ public static byte[] decrypt(byte[] data, String key) throws Exception { // 對密鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = ECKeyFactory.INSTANCE; ECPrivateKey priKey = (ECPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec); ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(priKey.getS(),priKey.getParams()); // 對數據解密 Cipher cipher = new NullCipher(); cipher.init(Cipher.DECRYPT_MODE, priKey, ecPrivateKeySpec.getParams()); return cipher.doFinal(data); } /** * 用公鑰加密 * @param data * @param privateKey * @return * @throws Exception */ public static byte[] encrypt(byte[] data, String privateKey) throws Exception { // 對公鑰解密 byte[] keyBytes = decryptBASE64(privateKey); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = ECKeyFactory.INSTANCE; ECPublicKey pubKey = (ECPublicKey) keyFactory.generatePublic(x509KeySpec); ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(pubKey.getW(), pubKey.getParams()); Cipher cipher = new NullCipher(); cipher.init(Cipher.ENCRYPT_MODE, pubKey, ecPublicKeySpec.getParams()); return cipher.doFinal(data); } /** * 取得私鑰 * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公鑰 * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } }
實際運營截圖:
聯繫QQ:137071249
QQ羣:793305035