為什么要加密?
(相關(guān)資料圖)
當(dāng)然是為了保密。
最早的密碼應(yīng)用,都伴隨著陰謀與戰(zhàn)爭(zhēng)。
中國(guó)古代的“陰符”、“陰書(shū)”就是其中的代表。
到了近代,二戰(zhàn)最著名的一個(gè)故事,就是納粹德國(guó)的Enigma密碼機(jī)
以及圖靈和他發(fā)明的密碼破解機(jī)。
可以說(shuō),現(xiàn)代戰(zhàn)爭(zhēng)中,信息安全極其重要
如果你的部署、命令都被對(duì)手知道
你收到的指令都是對(duì)手偽造的
這還怎么打?
在當(dāng)下,加密數(shù)據(jù)和密碼的應(yīng)用,
從軍事,到商業(yè)領(lǐng)域,以及科學(xué)界
乃至每個(gè)人普通的生活
如果沒(méi)有數(shù)據(jù)加密,每個(gè)人的信息都是透明的
想想可怕的電話詐騙,你還覺(jué)得自己的信息安全嗎?
有一句話說(shuō)的是:
大數(shù)據(jù)時(shí)代,沒(méi)有秘密
加密方式
最常見(jiàn)的計(jì)算機(jī)加密方式有三種:
對(duì)稱、非對(duì)稱、摘要
對(duì)稱的意思是:
我有一個(gè)秘鑰K,能把原文 A 加密成 A1,還能把 A1 還原成 Af(A, K) =A1f(A1, K) =A
對(duì)稱加密用途最為廣泛,
操作簡(jiǎn)單,速度快,
適合場(chǎng)合多樣
但缺點(diǎn)很明顯,秘鑰K太關(guān)鍵了
如果你需要讓密文被其他授信的人訪問(wèn)
必須給他發(fā)秘鑰
但問(wèn)題是,
只要得到秘鑰,就能破解一切,包括非法用戶
非對(duì)稱安全性稍微高一點(diǎn)
有2個(gè)秘鑰,一般是成對(duì)的公鑰和私鑰
通常是用公鑰加密,私鑰解密
這種情況下,解決了對(duì)稱加密的發(fā)送秘鑰問(wèn)題
現(xiàn)在公鑰是公開(kāi)的,私鑰只有我自己有
永遠(yuǎn)不發(fā)送,就不會(huì)泄密
摘要加密一般采用的是hash算法,
只加密不解密,
適合于只驗(yàn)證對(duì)不對(duì),而不驗(yàn)證是什么。
舉個(gè)樸素例子:
二中的學(xué)生,學(xué)號(hào)格式是 L220130103 格式
三中的學(xué)生,學(xué)號(hào)格式是 PLE821 格式
現(xiàn)在我要驗(yàn)證這個(gè)人是哪個(gè)學(xué)校的,
其實(shí)無(wú)需關(guān)注具體內(nèi)容,
簡(jiǎn)單判斷一下長(zhǎng)度就可以了
當(dāng)然真正的算法沒(méi)這么簡(jiǎn)單
下面具體來(lái)談
便于大家統(tǒng)一理解
我們建一個(gè)項(xiàng)目
統(tǒng)一使用hutool工具包
cn.hutool hutool-all 5.8.5
對(duì)稱加密
最簡(jiǎn)單的是des方法
他使用一個(gè)簡(jiǎn)單的秘鑰,就可以實(shí)現(xiàn)加密和解密
我們寫(xiě)一個(gè)junit的test,或者寫(xiě)一個(gè)main也可以
class Test1 {@Testvoid test() {String text0 = "這是原文";String key = "xiaomian";DES des = new DES(key.getBytes());String text1=des.encryptBase64(text0);System.out.println(text1);}}
運(yùn)行結(jié)果是 +iJWs7q8+dyiRBouA8lDBA==
我們使用秘鑰 “xiaomian”,
把“這是原文”,加密成了一個(gè)看不懂的字符串
然后開(kāi)始解密
class Test1 {@Testvoid test() {String key = "xiaomian";DES des = new DES(key.getBytes());String text2=des.decryptStr("+iJWs7q8+dyiRBouA8lDBA==");System.out.println(text2);}}
運(yùn)行結(jié)果是 這是原文
還是同一個(gè)key,
用相反的方法,把原文解出來(lái)了
操作非常簡(jiǎn)單。
des就是一個(gè)最簡(jiǎn)單的對(duì)稱加解密方法
類似的還有aes算法
可以使用hutool工具包,
操作差不多
非對(duì)稱加密
使用非對(duì)稱的主要原因
就是 安全、安全、還是安全
非對(duì)稱在性能方面和對(duì)稱沒(méi)的比
因此,建議非對(duì)稱使用短數(shù)據(jù)場(chǎng)合
而長(zhǎng)數(shù)據(jù)使用對(duì)稱實(shí)現(xiàn)。
最常用的是RSA算法
首先要生成一對(duì)秘鑰,這個(gè)就沒(méi)法人工創(chuàng)造了
我們可以借助工具
class Test2 {@Testvoid test() { KeyPair pair = SecureUtil.generateKeyPair("RSA"); String privateKey = Base64.encode(pair.getPrivate().getEncoded()); System.out.println("privateKey:" + privateKey); String publicKey = Base64.encode(pair.getPublic().getEncoded()); System.out.println("publicKey:" + publicKey);}}
輸出結(jié)果為:
privateKey:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALBgrUOQySQB72VrGyijYZcaNM26t49oaKlNddu4SLpEdJzpUnVjXtIi9Nj/DkFBXgSB9FYdrv7MpQWzTmLw0do6pcfo2cekmBGPnFRdChtEf8Npq0pAV2LlNahwkB8fxZcbQYaaWBuBkx7aHT09JGsEpi9P3y7ae4vwYmFlWgEHAgMBAAECgYBVBnXgEWb1Zb1rLaPNBl3gQrDb0Dv29QUnQIElZ4QfzypMDipDDqFCObnA9cuAZ6uUDrWj4fFfQXX39oU+KwtuESddT9rJw1hPSy2i5ityEyYO5OZQRJaTVWPWzpph+bqFLkngaOvlr3OBG7YtywUL0P8toz2pOQKpoQOkffetuQJBAP26GKiOcs/sKhrzuM/t0S2ERXXDcu07jWxJ8gioQBuQaM7AA14tbiRzaZm3Xt+cGPjHJUGEJpDvGLQ9MavEZDMCQQCx9S+JevTGpxHMX/R3uUawlTsks1keyd0rqBtqQQx7V9Bm8htrlVU3QbhacFd/FJodWX7mGOAO6nLVGK/5qXvdAkB13zSBadvwuDg/WSZsgoEA8kgKk4gaqeXjft7QIsnVhFsMYauu3tAiYvOWE9ghbbU0LeAi9a+s+UayxRMERzJ9AkA5Y7fL32I2+kQMI9nEDnUUl1u2bzxLaJAx9wm4T3gGAwDLYkKjhEoyArjAOcCN1AgLdQQuklEXnlYgENEXc6flAkEAwDbTBfOtuP/6S5nU0gX9D5fYlF/fz4YTfBjHC2dZ/wrmWlJA0f7QFf5DysQB9AXJX6ZWL/3LkMtHPafqBMKpJw==publicKey:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwYK1DkMkkAe9laxsoo2GXGjTNurePaGipTXXbuEi6RHSc6VJ1Y17SIvTY/w5BQV4EgfRWHa7+zKUFs05i8NHaOqXH6NnHpJgRj5xUXQobRH/DaatKQFdi5TWocJAfH8WXG0GGmlgbgZMe2h09PSRrBKYvT98u2nuL8GJhZVoBBwIDAQAB
看吧,鬼也看不懂
不過(guò)能用就行
接下來(lái),開(kāi)始使用秘鑰對(duì),進(jìn)行加密和解密
class Test2 {static String privateKey;static String publicKey;@BeforeAllstatic void createKey() { KeyPair pair = SecureUtil.generateKeyPair("RSA"); privateKey = Base64.encode(pair.getPrivate().getEncoded()); System.out.println("privateKey:" + privateKey); publicKey = Base64.encode(pair.getPublic().getEncoded()); System.out.println("publicKey:" + publicKey);}@Testvoid test() {String text = "這是原文";RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), privateKey, publicKey); String text1 = rsa.encryptBase64(text, KeyType.PublicKey); System.out.println("公鑰加密: " + text1); String text2 = rsa.decryptStr(text1, KeyType.PrivateKey); System.out.println("私鑰解密: " + text2);}}
輸出結(jié)果為:
公鑰加密: KSifTf6tS6LGlBT9LJC33VXzkXtaQEIGJcpf1BU2ptzRXTtBzvjx83EffCqntD7/M7ZciTr4MIBFBPFCxLs9NVEeC4K9/B8fQE/3hdsMzWBTnKQzQR2vd1i5mOgFaHYwTLwrq9Dbkv1YGluCb004YtLEqdjSO/Oljs7x2YVtvGc=私鑰解密: 這是原文
也可以反過(guò)來(lái)用
@Testvoid test() {String text = "這是原文";RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), privateKey, publicKey); String text1 = rsa.encryptBase64(text, KeyType.PrivateKey); System.out.println("私鑰加密: " + text1); String text2 = rsa.decryptStr(text1, KeyType.PublicKey); System.out.println("公鑰解密: " + text2);}
私鑰加密: Ty5YGXHUajKHtlmQ7yGYJtc39Rjb3IvSIm7WWg4+Ge6u8MDeJ3TLYZokgBbAMZRcZBZ8bIWiou12+KxoW8moRwke4PlWVipgwhC2l6qo7WtTMiwnGh+0+B8wnY3OySFK4ZeOMQFgYuiTL2uZqofLXyNzwID7GKCfWI6EL29wtbE=公鑰解密: 這是原文
對(duì)稱算法的特點(diǎn)就是
隨便先用誰(shuí),然后用另一個(gè)解
一般來(lái)說(shuō),有意義的信息,加密傳遞
建議使用 公鑰加密,私鑰解密
這種方法,確保信息只能由你指定的對(duì)象收到
另一種反過(guò)來(lái)的做法,
私鑰加密,公鑰解密
用于數(shù)字簽名場(chǎng)合
證明這個(gè)簽名是某人做的
因?yàn)橹挥兴兴约旱乃借€
摘要加密
摘要加密是單向的
能加不能解
主要目的是生成特征碼
常用算法包括 md5,sha 等等
class Test3 {@Testvoid test() {String text = "這是原文";String text1 = DigestUtil.md5Hex(text); System.out.println(text1);}}
輸出結(jié)果是:
531ffeed49bb13a6cf93049cc1e5ee53
比如系統(tǒng)密碼,一般采用摘要加密
假設(shè)我的密碼是 123456,
md5之后變成了 e10adc3949ba59abbe56e057f20f883e
如果有人能看到數(shù)據(jù)庫(kù)表,
哪怕他找到了我的密碼 e10adc3949ba59abbe56e057f20f883e,
也不知道我實(shí)際的密碼是123456
當(dāng)?shù)顷憰r(shí),會(huì)對(duì)用戶輸入的密碼再次md5,
如果結(jié)果還等于e10adc3949ba59abbe56e057f20f883e,
就表示輸對(duì)了密碼。
摘要加密的特點(diǎn)是
輸出結(jié)果位數(shù)是固定的
比如上面列出的md5,加密后永遠(yuǎn)是固定長(zhǎng)度
他的特點(diǎn)主要是:
輸入不同,加密結(jié)果就不同輸入相同,加密結(jié)果一定相同
現(xiàn)在一般md5用的也少,主要是長(zhǎng)度和復(fù)雜度
一般使用 sha256 或 sha512
他可以做簡(jiǎn)化驗(yàn)證
比如,我有一個(gè)文檔,大小為 100M
如何驗(yàn)證他的內(nèi)容發(fā)生串改
我們不可能拿2個(gè)100M的文件,逐個(gè)字節(jié)比較
這時(shí),只要對(duì)2者分別做摘要運(yùn)算,
得到一個(gè)短的字符串,對(duì)他們比較就可以了
這種驗(yàn)證的特點(diǎn)是:我知道你對(duì)和不對(duì),但我不知道哪錯(cuò)了
總結(jié)
三種方法中,一般使用原則是
速度快,用對(duì)稱安全高/數(shù)據(jù)少,用非對(duì)稱用于驗(yàn)證對(duì)錯(cuò),保留特征碼,用摘要大家可以試試,順便安利一下hutool,
非常優(yōu)秀的工具包
之后我們會(huì)專文介紹國(guó)密算法
關(guān)鍵詞: