面試官:說一說你常用的加密演算法有哪些?
加密演算法通常被分為兩種:對稱加密和非對稱加密。其中,對稱加密演算法在加密和解密時使用的金鑰相同;非對稱加密演算法在加密和解密時使用的金鑰不同,分為公鑰和私鑰。此外,還有一類叫做訊息摘要演算法,是對資料進行摘要並且不可逆的演算法。
這次我們瞭解一下訊息摘要演算法。
訊息摘要演算法
訊息摘要演算法是把任意長度的輸入揉和而產生長度固定的偽隨機結果的演算法。在資訊保安中,有許多重要的應用,都使用了訊息摘要演算法來實現,例如數字簽名、訊息認證碼。
對於任何一個給定的資料,訊息摘要演算法都很容易就能運算出摘要結果。難以由一個已知的摘要結果,去推算出原始的資料。在不更動摘要結果的前提下,修改資料內容是不可行的。對於兩個不同的資料,只有極低的機率會產生相同的摘要結果。
常見的對稱加密演算法有:MD5演算法、SHA。
MD5演算法
MD5演算法(Message Digest 5)是一種密碼雜湊函式,產生出一個128位的雜湊值,可以用一個長度為32的十六進位制字串表示。
MD5演算法是由美國密碼學家Ronald Linn Rivest(這位大佬就是發明RSA演算法的R)設計的,於1992年公開,用來取代之前的MD4演算法(再之前還有MD3演算法、MD2演算法)。
MD5演算法把原資料按每組512位大小進行分組,然後每一分組又被劃分為16個32位子分組,再和事先定義好的4個幻數進行了一系列的位運算迴圈,最後得到四個32位的分組,將這四個32位分組級聯後將生成一個128位雜湊值。
我們用Java寫個例子:
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Md5Util {
private static final String MD5 = "MD5";
private static final Charset CHARSET = StandardCharsets.UTF_8;
public static String build(String input) throws NoSuchAlgorithmException {
MessageDigest md5 = MessageDigest.getInstance(MD5);
byte[] digest = md5.digest(input.getBytes(CHARSET));
return new BigInteger(1, digest).toString(16);
}
public static void main(String[] args) throws NoSuchAlgorithmException {
String msg = "我喜歡你,可以做我女朋友嗎?";
System.out.println("原文:" + msg);
System.out.println("摘要:" + build(msg));
}
}
執行結果如下:
原文:我喜歡你,可以做我女朋友嗎?
摘要:f9fa148f2cfffda9b5e15a9e5bf34b66
2004年,MD5演算法被證實無法防止碰撞攻擊,因此不適用於安全性認證。
2009年,中國科學院的謝濤和馮登國僅用了$2^{20.96}$的碰撞演算法複雜度,破解了MD5的碰撞抵抗,該攻擊在普通計算機上執行只需要數秒鐘。
2011年,IETF(Internet Engineering Task Force,網際網路工程任務組)釋出RFC 6151,禁止MD5用作金鑰雜湊訊息認證碼。
總之,MD5已經不安全,不要再繼續使用了。
SHA
SHA(Secure Hash Algorithm,安全雜湊演算法)是一個密碼雜湊函式家族,是FIPS(Federal Information Processing Standards,聯邦資訊處理標準)所認證的安全雜湊演算法。
SHA家族包含一套逐步發展而來演算法,有1993年釋出的SHA-0、1995年釋出的SHA-1、2001年釋出的SHA-2、2015年釋出的SHA-3。
由於對MD5出現成功的破解,以及對SHA-0和SHA-1出現理論上破解的方法,所以推薦使用SHA-2,或者更安全的SHA-3。
我們用Java寫個SHA-2的例子:
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ShaUtil {
private static final String SHA_256 = "SHA-256";
private static final String SHA_512 = "SHA-512";
private static final String SHA3_256 = "SHA3-256";
private static final String SHA3_512 = "SHA3-512";
private static final Charset CHARSET = StandardCharsets.UTF_8;
public static String build(String input, String algorithm) throws NoSuchAlgorithmException {
MessageDigest md5 = MessageDigest.getInstance(algorithm);
byte[] digest = md5.digest(input.getBytes(CHARSET));
return new BigInteger(1, digest).toString(16);
}
public static void main(String[] args) throws NoSuchAlgorithmException {
String msg = "我喜歡你,可以做我女朋友嗎?";
System.out.println("原文:" + msg);
System.out.println("SHA2-256摘要:" + build(msg, SHA_256));
System.out.println("SHA2-512摘要:" + build(msg, SHA_512));
System.out.println("SHA3-256摘要:" + build(msg, SHA3_256));
System.out.println("SHA3-512摘要:" + build(msg, SHA3_512));
}
}
執行結果如下:
原文:我喜歡你,可以做我女朋友嗎?
SHA2-256摘要:b6da8ee261f2b852c1140cf181e8d64b180ca6c884651ddb871bdff25afc836b
SHA2-512摘要:d65f455eb38a565fae8e7c3ea6dbc005612071d5e57b688f32674e9641ab9aa6f056381222ba47cc973c86380f24fd10f4078ad7bfd3d498210d721734740a5a
SHA3-256摘要:fc5f1427fc5a1bb2f231eec52fdaa5ac84652730143a3c7598dc2148ccd05cec
SHA3-512摘要:5d8ba707c40c39f37c8cffd2eabf8da8d6d4ede70c697402a5e5ea6228c5710c3d76a6abbc1d46413bfced66280f72621feac12ce3ef49aed60902091ca1979f
JDK8及以下版本不支援SHA-3,所以執行以上程式碼時會出現NoSuchAlgorithmException
: SHA3-256 MessageDigest not available
異常。
總結
訊息摘要演算法是把任意長度的輸入揉和而產生長度固定的偽隨機結果的演算法。常見的對稱加密演算法有:MD5演算法、SHA。
MD5演算法不要再繼續使用了。SHA家族中,推薦使用SHA-2,或者更安全的SHA-3。
竟然已經看到這裡了,你我定是有緣人,留下你的點贊和關注,他日必成大器。
微信公眾號:萬貓學社
微信掃描二維碼
關注後回覆「電子書」
獲取12本Java必讀技術書籍