什么是加密算法
轉(zhuǎn)載自??什么是加密算法
Java的加密知識(shí)也是Java常見(jiàn)的領(lǐng)域之一,加密技術(shù)的底層確實(shí)很復(fù)雜,運(yùn)用了大量的數(shù)學(xué)知識(shí),要弄明白非常復(fù)雜。但是Java語(yǔ)言中運(yùn)用密碼加密工具卻是非常簡(jiǎn)單。我們?cè)贘ava里面運(yùn)用這些加密技術(shù),只需要把原理和使用場(chǎng)景等搞明白就可以了,具體底層實(shí)現(xiàn)不用研究。
常用的加密算法有對(duì)稱(chēng)加密算法,非對(duì)稱(chēng)加密算法,哈希算法,數(shù)字簽名等幾類(lèi)。? ??
對(duì)稱(chēng)加密顧名思義就是加密和解密是對(duì)稱(chēng)的,加密時(shí)用一個(gè)秘鑰去加密,解密時(shí)用同一個(gè)秘鑰去解密,由信息發(fā)送方和接收方共同約定一個(gè)秘鑰。缺點(diǎn)是風(fēng)險(xiǎn)都在這個(gè)秘鑰上面,一旦被竊取,信息會(huì)暴露。所以安全級(jí)別不夠高。常用對(duì)稱(chēng)加密算法有DES,3DES,AES等。在jdk中也都有封裝。
非對(duì)稱(chēng)加密,顧名思義就是加密與解密的過(guò)程不是對(duì)稱(chēng)的,不是用的同一個(gè)秘鑰。非對(duì)稱(chēng)加密有個(gè)公私鑰對(duì)的概念,也就是有兩把秘鑰,一把是公鑰,一把是私鑰,一對(duì)公私鑰有固定的生成方法,在加密的時(shí)候,用公鑰去加密,接收方再用對(duì)應(yīng)的私鑰去解密。使用時(shí)可以由接收方生成公私鑰對(duì),然后將公鑰傳給加密方,這樣私鑰不會(huì)在網(wǎng)絡(luò)中傳輸,沒(méi)有被竊取的風(fēng)險(xiǎn)。比如github底層的ssh協(xié)議就是公私鑰非對(duì)稱(chēng)加密。并且公鑰是可以由私鑰推導(dǎo)出來(lái)的,反過(guò)來(lái)卻不行,由通過(guò)公鑰無(wú)法推導(dǎo)出私鑰。常用算法有RSA,ECC等。ECC也是比特幣底層用的比較多的算法。通過(guò)和對(duì)稱(chēng)加密的對(duì)比,可以看到,非對(duì)稱(chēng)加密解決了秘鑰傳輸中的安全問(wèn)題。
哈希算法,簡(jiǎn)單說(shuō)就是將任意數(shù)據(jù)都轉(zhuǎn)換成一個(gè)固定長(zhǎng)度的字符串。通過(guò)哈希后的值幾乎無(wú)法推導(dǎo)出原文。而且兩個(gè)不同的原文哈希后結(jié)果一定不同。常用算法有MD5,SHA256等等。常用場(chǎng)景,md5常用場(chǎng)景是數(shù)據(jù)庫(kù)的密碼存儲(chǔ)。sha256在挖礦中可以用到。
非對(duì)稱(chēng)加密也有一個(gè)問(wèn)題,就是內(nèi)容在發(fā)送前可能被篡改,因?yàn)楣€是有可能被竊取的,所以竊取者完全可以改為發(fā)送別的內(nèi)容。
解決的辦法就是數(shù)字簽名。數(shù)字簽名和非對(duì)稱(chēng)加密是反過(guò)來(lái)的,也是有公私鑰對(duì),但是是用私鑰簽名,用公鑰去驗(yàn)證簽名。比如發(fā)送方除了發(fā)送用公鑰加密后的密文,還要發(fā)送簽名,簽名內(nèi)容通常是密文哈希后的字符串,接收方首先驗(yàn)證簽名是否正確,如果正確那么密文解密后就是真正需要并且沒(méi)有被篡改過(guò)的內(nèi)容。注意,簽名和非對(duì)稱(chēng)用的是兩對(duì)不同的公私鑰。
上面是對(duì)幾個(gè)加密算法的一個(gè)簡(jiǎn)單講解,除了上面的還有base58等,比特幣底層安全也是依賴(lài)于加密。后面會(huì)一個(gè)一個(gè)介紹要用到的加密算法的介紹和使用,但是僅僅是使用,底層不會(huì)講。
MD5
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于確保信息傳輸完整一致。是計(jì)算機(jī)廣泛使用的雜湊算法之一(又譯摘要算法、哈希算法),主流編程語(yǔ)言普遍已有MD5實(shí)現(xiàn)。將數(shù)據(jù)(如漢字)運(yùn)算為另一固定長(zhǎng)度值,是雜湊算法的基礎(chǔ)原理,MD5的前身有MD2、MD3和MD4。
MD5算法具有以下特點(diǎn):
1、壓縮性:任意長(zhǎng)度的數(shù)據(jù),算出的MD5值長(zhǎng)度都是固定的。
2、容易計(jì)算:從原數(shù)據(jù)計(jì)算出MD5值很容易。
3、抗修改性:對(duì)原數(shù)據(jù)進(jìn)行任何改動(dòng),哪怕只修改1個(gè)字節(jié),所得到的MD5值都有很大區(qū)別。
4、強(qiáng)抗碰撞:已知原數(shù)據(jù)和其MD5值,想找到一個(gè)具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的。
MD5的作用是讓大容量信息在用數(shù)字簽名軟件簽署私人密鑰前被"壓縮"成一種保密的格式(就是把一個(gè)任意長(zhǎng)度的字節(jié)串變換成一定長(zhǎng)的十六進(jìn)制數(shù)字串)。除了MD5以外,其中比較有名的還有sha-1、RIPEMD以及Haval等。
JDK就自帶了md5加密算法,直接調(diào)用很方便。需要引入一個(gè)類(lèi):
import java.security.MessageDigest;
首先創(chuàng)建一個(gè)springboot項(xiàng)目,加上一個(gè)web以來(lái),內(nèi)容如下:
?
SHA256
學(xué)Java的對(duì)哈希算法都不陌生,畢竟每個(gè)類(lèi)都有hashCode方法。
散列算法(Hash Algorithm),又稱(chēng)哈希算法,雜湊算法,是一種從任意文件中創(chuàng)造小的數(shù)字「指紋」的方法。與指紋一樣,散列算法就是一種以較短的信息來(lái)保證文件唯一性的標(biāo)志,這種標(biāo)志與文件的每一個(gè)字節(jié)都相關(guān),而且難以找到逆向規(guī)律。因此,當(dāng)原有文件發(fā)生改變時(shí),其標(biāo)志值也會(huì)發(fā)生改變,從而告訴文件使用者當(dāng)前的文件已經(jīng)不是你所需求的文件。
一個(gè)優(yōu)秀的 hash 算法,將能實(shí)現(xiàn):
正向快速:給定明文和 hash 算法,在有限時(shí)間和有限資源內(nèi)能計(jì)算出 hash 值。
逆向困難:給定(若干) hash 值,在有限時(shí)間內(nèi)很難(基本不可能)逆推出明文。
輸入敏感:原始輸入信息修改一點(diǎn)信息,產(chǎn)生的 hash 值看起來(lái)應(yīng)該都有很大不同。
沖突避免:很難找到兩段內(nèi)容不同的明文,使得它們的 hash 值一致(發(fā)生沖突)。即對(duì)于任意兩個(gè)不同的數(shù)據(jù)塊,其hash值相同的可能性極小;對(duì)于一個(gè)給定的數(shù)據(jù)塊,找到和它hash值相同的數(shù)據(jù)塊極為困難。
但在不同的使用場(chǎng)景中,如數(shù)據(jù)結(jié)構(gòu)和安全領(lǐng)域里,其中對(duì)某一些特點(diǎn)會(huì)有所側(cè)重。
安全散列算法(英語(yǔ):Secure Hash Algorithm,縮寫(xiě)為SHA)是一個(gè)密碼散列函數(shù)家族,是FIPS所認(rèn)證的安全散列算法。能計(jì)算出一個(gè)數(shù)字消息所對(duì)應(yīng)到的,長(zhǎng)度固定的字符串(又稱(chēng)消息摘要)的算法。且若輸入的消息不同,它們對(duì)應(yīng)到不同字符串的機(jī)率很高。
SHA家族的五個(gè)算法,分別是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512。主要適用于數(shù)字簽名標(biāo)準(zhǔn)(DigitalSignature Standard DSS)里面定義的數(shù)字簽名算法(Digital Signature Algorithm DSA)。比特幣里面的就是SHA-256算法。
說(shuō)簡(jiǎn)單一些,就是對(duì)一個(gè)對(duì)象的多個(gè)關(guān)鍵不重復(fù)信息組合起來(lái),通過(guò)算法生成一個(gè)加密字符串。
繼續(xù)上一個(gè)項(xiàng)目,在對(duì)應(yīng)的包下建一個(gè)工具類(lèi):
package btcdemo.btcdemo.security;
public class Sha256Utils
引入的加密類(lèi)和md5一樣:
import java.security.MessageDigest;
下面是算法的具體內(nèi)容:
?
下面是算法的測(cè)試類(lèi)內(nèi)容:
?
運(yùn)行可以看到如下結(jié)果:
?
目前目錄結(jié)構(gòu)如下:
?
項(xiàng)目代碼:https://github.com/guoyb1990/btc-demo.git
?
BASE64&BASE58
Base64是網(wǎng)絡(luò)上最常見(jiàn)的用于傳輸8Bit字節(jié)碼的編碼方式之一,Base64就是一種基于64個(gè)可打印字符來(lái)表示二進(jìn)制數(shù)據(jù)的方法。可查看RFC2045~RFC2049,上面有MIME的詳細(xì)規(guī)范。
Base64編碼是從二進(jìn)制到字符的過(guò)程,可用于在HTTP環(huán)境下傳遞較長(zhǎng)的標(biāo)識(shí)信息。例如,在Java Persistence系統(tǒng)Hibernate中,就采用了Base64來(lái)將一個(gè)較長(zhǎng)的唯一標(biāo)識(shí)符(一般為128-bit的UUID)編碼為一個(gè)字符串,用作HTTP表單和HTTP GET URL中的參數(shù)。在其他應(yīng)用程序中,也常常需要把二進(jìn)制數(shù)據(jù)編碼為適合放在URL(包括隱藏表單域)中的形式。此時(shí),采用Base64編碼具有不可讀性,需要解碼后才能閱讀。
Base64編碼要求把3個(gè)8位字節(jié)(3*8=24)轉(zhuǎn)化為4個(gè)6位的字節(jié)(4*6=24),之后在6位的前面補(bǔ)兩個(gè)0,形成8位一個(gè)字節(jié)的形式。 如果剩下的字符不足3個(gè)字節(jié),則用0填充,輸出字符使用‘=’,因此編碼后輸出的文本末尾可能會(huì)出現(xiàn)1或2個(gè)‘=’。?
jdk的工具包中就自帶base64的工具類(lèi),使用base64的方法也非常簡(jiǎn)單,先新建一個(gè)工具類(lèi):
base64是可逆的,加密解密內(nèi)容如下:
可以看到使用非常簡(jiǎn)單,下面是測(cè)試類(lèi)內(nèi)容:
執(zhí)行測(cè)試方法,結(jié)果如下:
可以看到base64非常簡(jiǎn)單。
base58和base64一樣是一種二進(jìn)制轉(zhuǎn)可視字符串的算法,主要用來(lái)轉(zhuǎn)換大整數(shù)值。區(qū)別是,轉(zhuǎn)換出來(lái)的字符串,去除了幾個(gè)看起來(lái)會(huì)產(chǎn)生歧義的字符,如 0 (零), O (大寫(xiě)字母O), I (大寫(xiě)的字母i) and l (小寫(xiě)的字母L) ,和幾個(gè)影響雙擊選擇的字符,如/, +。結(jié)果字符集正好58個(gè)字符(包括9個(gè)數(shù)字,24個(gè)大寫(xiě)字母,25個(gè)小寫(xiě)字母)。不同的應(yīng)用實(shí)現(xiàn)中,base58 最后查詢(xún)的字母表可能不同,所以沒(méi)有具體的標(biāo)準(zhǔn)。
可以看出,base58是base64的一種人性化的版本,是站在使用者的角度考慮的。
新建一個(gè)Base58的工具類(lèi),目錄結(jié)構(gòu)如下:
工具類(lèi)的大概內(nèi)容結(jié)構(gòu)如下:
因?yàn)閮?nèi)容過(guò)多,可以通過(guò)下載源碼查看。
下面是測(cè)試代碼:
?
運(yùn)行結(jié)果如下:
?
可以看到,base58的使用方法是一樣的。
項(xiàng)目代碼:https://github.com/guoyb1990/btc-demo.git
總結(jié)
- 上一篇: 什么是缓存击穿
- 下一篇: jdbc事务和事务的隔离级别