為什么要加密?


(相關(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)鍵詞: