aes(關(guān)于aes的基本詳情介紹)

來(lái)源:Lee

原文地址:http://davidleee.com/2016/04/26/about-aes-encryption/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

前世今生

AES 的出現(xiàn)就是為了取代原來(lái)的數(shù)據(jù)加密標(biāo)準(zhǔn)(DES),作為爺爺級(jí)的加密算法,DES在風(fēng)光過(guò)后也是到了該退休的年紀(jì)了。

關(guān)于DES

在繼續(xù)了解AES之前,不妨先看看被它取代的DES是什么。

它的全稱(chēng)為Data Encryption Standard,是一種對(duì)稱(chēng)密鑰加密塊算法,大致的加密流程長(zhǎng)這個(gè)樣子:

?

在進(jìn)入到加密流程之前,64位的塊被拆分為兩個(gè)32位的子塊,并作為 IP 的兩個(gè)輸入。中間的 F 是 Feistel function,算法中的密鑰就是在這個(gè)函數(shù)中被用到的。

塊加密:Block cipher, 也叫作分組加密,是將明文分成多個(gè)等長(zhǎng)模塊(block),使用確定的算法和對(duì)稱(chēng)密鑰對(duì)每組分別加密解密的方式。

DES 在1976年曾經(jīng)風(fēng)光一時(shí),被美國(guó)聯(lián)邦政府的國(guó)家標(biāo)準(zhǔn)局定為聯(lián)邦資料處理標(biāo)準(zhǔn)(FIPS)。然而因?yàn)樗皇怯昧?6位的密鑰,所以在當(dāng)下已經(jīng)不是一種安全的加密方法。在1999年1月,已經(jīng)有組織在22小時(shí)15分鐘內(nèi)公開(kāi)破解了一個(gè)DES密鑰。

后來(lái)出現(xiàn)了一種改進(jìn)的 DES,叫 TDES 或 3DES。它本質(zhì)上就是把密鑰個(gè)數(shù)增加到了3個(gè),并沒(méi)有算法上的改進(jìn)。(感覺(jué)很兒戲的樣子)

在2001年,DES已經(jīng)不再是國(guó)際標(biāo)準(zhǔn)科技協(xié)會(huì)(NIST,前 FIPS)的一個(gè)標(biāo)準(zhǔn),而且也開(kāi)始慢慢被AES所取代。

言歸正傳

AES,全稱(chēng)為Advanced Encryption Standard,原名叫做Rijndael 加密法。(還是新名字好念)

至于一開(kāi)始為什么有個(gè)這么拗口的名字,因?yàn)閮晌蛔髡叩拿质?Joan Daemen 和 Vincent Rijmen,發(fā)現(xiàn)為什么了嗎?這是不是密碼學(xué)家約定俗成的某種命名方式呢?

2001年11月26日,美國(guó)的 NIST 公布了 AES 這一標(biāo)準(zhǔn),并開(kāi)始了長(zhǎng)達(dá)5年的標(biāo)準(zhǔn)化進(jìn)程,直到 Rijndael 被選為最適合的方法。

在2002年5月26日,AES 成為了一項(xiàng)聯(lián)邦政府標(biāo)準(zhǔn)。它還是聯(lián)邦安全局(NSA)批準(zhǔn)的唯一一種用來(lái)加密頂級(jí)機(jī)密信息的公開(kāi)加密方法。

也就是說(shuō),如果你想要黑 FBI,也許可以試試看 AES 解密 :)

嚴(yán)格來(lái)說(shuō),AES 和 Rijndael 并不完全一樣。AES 使用的是固定128位大小的塊,密鑰的大小只能是128位、192位或256位;而 Rijndael 使用的塊大小和密鑰長(zhǎng)度可以是在128位和256位之間能被32整除的任意值,相對(duì)來(lái)說(shuō)靈活性高了很多。

主要過(guò)程

AES加密算法的組成可以分成4個(gè)主要部分:

AddRoundKey

SubBytes

ShiftRows

MixColumns

簡(jiǎn)單來(lái)說(shuō),就是將上面的幾個(gè)部分組合起來(lái)形成三種不同的序列,然后把這些過(guò)程序列重復(fù)執(zhí)行若干個(gè)回合,具體的循環(huán)次數(shù)由密鑰的長(zhǎng)度決定:

128位密鑰:循環(huán)10次

192位密鑰:循環(huán)12次

256位密鑰:循環(huán)14次

這三種序列是:

首次循環(huán):

AddRoundKey

一般循環(huán):

SubBytes

ShiftRows

MixColumns

AddRoundKey

末尾循環(huán):

SubBytes

ShiftRows

AddRoundKey

那么這幾個(gè)部分到底是干了些什么呢?

AddRoundKey

在每一次循環(huán)中,通過(guò) Rijndael 密鑰生成方案(https://en.wikipedia.org/wiki/Rijndael_key_schedule)從主密鑰中生成一個(gè)子密鑰,這個(gè)子密鑰的大小應(yīng)該等同于塊的大小,并且以列優(yōu)先的方式排列在一個(gè)矩陣?yán)铮總€(gè)塊也是以這樣的方式排列在矩陣?yán)锏模?/p>

接下來(lái)將這個(gè)子密鑰的值與塊上對(duì)應(yīng)位置的值 XOR 起來(lái),形成一個(gè)新的矩陣,到這里這一過(guò)程就算完成了。?

SubBytes

這一步會(huì)使用到一個(gè)叫做 Rijndael S-box 的東西,它其實(shí)就是一個(gè)8位的代換表,每一個(gè)字節(jié)的數(shù)據(jù)都可以在表中查到對(duì)應(yīng)的代換結(jié)果。只要這個(gè) S-box 在構(gòu)建的時(shí)候足夠好,就可以大大降低這次加密的線(xiàn)性關(guān)系。下面是一個(gè)6位 S-box 的例子,輸入的值是011011,輸出的值是1001。

?將塊矩陣中的每一個(gè)元素通過(guò) S-box 進(jìn)行代換,組成一個(gè)代換后的矩陣,就是 SubBytes 這一步的工作。

ShiftRows

這一步容易理解,就是把塊矩陣中的每一行都進(jìn)行一個(gè)向左循環(huán)移位,最后的效果是要讓輸出矩陣的每一列上的元素都屬于輸入矩陣原本不同的列。

這樣做可以保證每一列上的元素都是非線(xiàn)性相關(guān)的。?

MixColumns

這個(gè)部分會(huì)接受4個(gè)字節(jié)的輸入,并輸出4個(gè)字節(jié),而且每一個(gè)字節(jié)輸入的字節(jié)都會(huì)對(duì)輸出造成影響,所以它跟上面的 ShiftRows 一起為加密算法提供了良好的擴(kuò)散性.

擴(kuò)散性(Diffusion):如果改變了任意1位的原文,密文中一半以上的位也應(yīng)該會(huì)跟著改變;反過(guò)來(lái),改變了任意1位密文,得到的原文也應(yīng)該有一半以上的位被改變。—— Stallings, William (2014). Cryptography and Network Security (6th ed.)

簡(jiǎn)單來(lái)說(shuō),這一步就是講輸入矩陣的每一列與一個(gè)固定的多項(xiàng)式在一定條件下相乘。最終得到的將會(huì)是一個(gè)與輸入矩陣完全不一樣的輸出矩陣。

?

更多資料

伽羅華域(Galois Field,GF,有限域)乘法運(yùn)算(http://blog.csdn.net/mengboy/article/details/1514445)

Confusion and diffusion(https://en.wikipedia.org/wiki/Confusion_and_diffusion)

填充算法

對(duì)于塊加密算法來(lái)說(shuō),如果數(shù)據(jù)的長(zhǎng)度不滿(mǎn)一個(gè)塊的大小,我們就需要主動(dòng)填充一些數(shù)據(jù),讓這個(gè)塊的大小可以滿(mǎn)足要求,于是,一個(gè)合適的填充算法就顯得尤為重要。

經(jīng)過(guò)導(dǎo)師的提醒并且在網(wǎng)上讀了一些博客之后發(fā)現(xiàn),Java端與iOS端使用的AES填充算法是不一樣的(http://my.oschina.net/nicsun/blog/95632),在 Java 端上使用的是 PKCS5Padding ,而在iOS端上使用的是 PKCS7Padding 。所以就會(huì)導(dǎo)致在其中一端上加解密沒(méi)有問(wèn)題,但是把密文發(fā)到另一端上解密就會(huì)得到完全不同的結(jié)果。

P.S. 這里說(shuō)到的 Java 端 應(yīng)該是指服務(wù)器端,Android 端上不知道有沒(méi)有這個(gè)問(wèn)題。

PKCS5 相當(dāng)于是 PKCS7 的一個(gè)子集,因?yàn)?PKCS7 理論上支持1~255字節(jié)的塊大小填充,而 PKCS5 只支持8字節(jié)的塊大小填充。其實(shí) PKCS5 更多是應(yīng)用在 DES/3DES 上。

具體的填充過(guò)程也非常好理解,直接舉例子好了:比如說(shuō)塊大小為8字節(jié)的加密算法,現(xiàn)在有一串長(zhǎng)度為9的數(shù)據(jù):

FF FF FF FF FF FF FF FF FF(9個(gè)FF)

使用 PKCS7 算法去填充的話(huà),結(jié)果就是這樣的

FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07(9個(gè)FF和7個(gè)07)

填充的目的就是把塊給補(bǔ)滿(mǎn),所以這里填充的長(zhǎng)度為7;而采用 PKCS7 算法的話(huà),填充的每一個(gè)字節(jié)都是填充長(zhǎng)度的十六進(jìn)制數(shù),那就也是7。

有趣的是,如果采用 PKCS5 去填充,因?yàn)樗哪繕?biāo)塊大小是8,所以這里會(huì)填充一個(gè)01。詳情可以參考Can AES use PKCS5 padding(http://crypto.stackexchange.com/a/11274)里的最佳答案。

參考資料

Advanced Encryption Standard(https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)

Rijndael 密鑰生成方案(https://en.wikipedia.org/wiki/Rijndael_key_schedule)

伽羅華域(Galois Field,GF,有限域)乘法運(yùn)算(http://blog.csdn.net/mengboy/article/details/1514445)

Confusion and diffusion(https://en.wikipedia.org/wiki/Confusion_and_diffusion)

關(guān)于AES256算法java端加密,ios端解密出現(xiàn)無(wú)法解密問(wèn)題的解決方案(http://my.oschina.net/nicsun/blog/95632)

Can AES use PKCS5 padding(http://crypto.stackexchange.com/questions/11272/can-aes-use-pkcs5-padding)

Vanilla社區(qū)發(fā)起?晨讀計(jì)劃?,每天堅(jiān)持積累一點(diǎn),今天的努力至少讓我們比昨天更進(jìn)一步。

?晨讀計(jì)劃? 期待你的加入... ...

Vanilla:基于OpenResty的高性能Web應(yīng)用開(kāi)發(fā)框架

我們的微信號(hào):Vanilla-OpenResty

我們的QQ群:205773855、481213820、34782325

晨讀計(jì)劃

2016/04/28

轉(zhuǎn)載注明出處:華峰博客網(wǎng)

內(nèi)容版權(quán)聲明:除非注明,否則皆為本站原創(chuàng)文章。