目錄
AES
發展史
概述
輪函式F
位元組代換
行移位
列混淆
輪密鑰加
密鑰編排
AES和DES的不同之處
分組模式CTR
AES的Go實作
aes包
cipher包
加密/解密
參考
本篇介紹分組密碼AES的相關內容及Go實作,分組密碼演算法設計思想及其他分組模式可查看文章:Go-Des和3Des演算法詳解與代碼
AES
發展史
RSA公司舉辦過破譯DES的比賽(DES Challenge):
- 1997年的DES ChallengeI中用了96天;
- 1998年的DES ChallengeII-1中用了41天;
- 1998年的DES ChallengeII-2中用了56小時;
- 1999年的DES ChallengeII中用了22小時15分鐘,
DES被破解,3DES過度后終于迎來了AES,
- 1997年4月15日,美國ANSI向全球發起征集AES(advanced encryptionstandard)的活動,并為此成立了AES作業小組,
- 1997年9月12日,美國聯邦登記處公布了正式征集AES候選演算法的通告,對AES的基本要求是:比三重DES快、至少與三重DES一樣安全、資料分組長度為128位元、密鑰長度為128/192/256位元,
- 1998年8月12日,在首屆AES候選會議(first AES candidate conference)上公布了AES的15個候選演算法,任由全世界各機構和個人攻擊和評論,
- 1999年3月,在第2屆AES候選會議(second AES candidate conference)上經過對全球各密碼機構和個人對候選演算法分析結果的討論,從15個候選演算法中選出了5個,分別是RC6、Rijndael、SERPENT、Twofish和MARS,
- 2000年4月13日至14日,召開了第3屆AES候選會議(third AES candidateconference),繼續對最后5個候選演算法進行討論,
- 2000年10月2日,NIST宣布Rijndael(Rijndael由比利時的Joan Daemen和Vincent Rijmen設計,演算法的原型是 Square演算法)作為新的AES,經過3年多的公開討論,Riindael終于脫穎而出,
概述
- 分組加密演算法:明文和密文分組可變長度,
- SPN(S變換和P變換組成的變換網路)結構:輪函式包含代換層一置換層一密鑰混合層,
| 版本 | 密鑰長度 | 分組長度 | 迭代輪數 |
|---|---|---|---|
| AES-128 | 4 | 4 | 10 |
| AES-192 | 6 | 4 | 12 |
| AES-256 | 8 | 4 | 14 |
輪函式F
位元組代換
列的每個元素作為輸入用來指定S盒的地址:前4位指定S盒的行,后4位指定S盒的列,由行和列所確定的S盒位置的元素取代了明文矩陣中相應位置的元素,

S盒如下(反向使用S^-1盒即可)

明文:10000111,前4位為8,后四位為7,替換為S(8,7)=17=00010001
行移位
行移位操作是作用于S盒的輸出的,其中,列的4個行 螺旋 地左移,即第0行左移0位元組,第1行左移1位元組,第2行左移2位元組,第3行左移3位元組,如下圖所示,從該圖中可以看出, 這使得列完全進行了重排,即在移位后的每列中,都包含有 未移位前每個列的一個位元組,接下來就可以進行列內混合了, (逆向行移位變換將中間態資料的后三行執行相反方向的移位操作)

列混淆
在列混淆變換中,將行移位后的狀態陣列的每個列視為GF()上的多項式,再與一個固定的多項式c(x)進行模
乘法,要求c(x) 是模
可逆的多項式, c(x)=’03’
+’01’
+’01’x+’02’,

輪密鑰加
密鑰編排
密鑰編排指從種子密鑰得到輪密鑰的程序,AES的密鑰編排由密鑰擴展和輪密鑰選取兩部分組成,其基本原則如下:
- 輪密鑰的總位元數等于輪數加1再乘以分組長度;如128位元的明文經過10輪的加密,則總共需 要(10+1)*128=1408位元的密鑰.,
- 種子密鑰被擴展成為擴展密鑰;
- 輪密鑰從擴展密鑰中取,其中第1輪輪密鑰取擴展密鑰的前
個字,第2輪輪密鑰取接下來的
個字,依次類推,
密鑰擴展
擴展密鑰是以4位元組字為元素的一維陣列,表示為W[* (Nr +1)],其中前
個字取為種子密鑰, 以后每個字按遞回方式定義,擴展演算法根據
≤6和
>6有所不同,
輪密鑰選取
輪密鑰i(即第i個輪密鑰)由輪密鑰緩沖字 W[* i]到W[
*(i+1)]給出

AES和DES的不同之處
- AES的密鑰長度(128位、192位、256位)是可變的,而DES的 密鑰長度固定為56位,
- DES是面向位元的運算,AES是面向位元組的運算,
- AES的加密運算和解密運算不一致,因而加密器不能同時 用作解密器,而DES的加密器可用作解密器,只是子密鑰 的順序不同,
分組模式CTR
加密不同的明文分組所用的計數器值必須不同(模運 算,其中d是分組長度),

AES的Go實作
aes包
func NewCipher(key []byte) (cipher.Block, error)
創建一個cipher.Block介面,引數key為密鑰,長度只能是16、24、32位元組,用以選擇AES-128、AES-192、AES-256,
cipher包
func NewCTR(block Block, iv []byte) Stream
回傳一個計數器模式的、底層采用block生成key流的Stream介面,初始向量iv的長度必須等于block的塊尺寸,
stream介面的方法
XORKeyStream(dst, src []byte)
從加密器的key流和src中依次取出位元組二者xor后寫入dst,src和dst可指向同一記憶體地址
加密/解密
- 使用aes.NewCipher獲取塊
- 使用cipher.CTR轉為CTR模式流
- 使用stearm.XORKeyStream進行加解密
// plainText:明文
// iv: 初始化向量
// key:密鑰
// 回傳密文/明文,以及錯誤
func AesEncrypt(plainText, iv,key []byte) ([]byte,error) {
block, err :=aes.NewCipher(key)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,util.Error(file,line+1,errors.AesKeyError)
}
if len(iv) != block.BlockSize(){
_, file, line, _ := runtime.Caller(0)
return nil,util.Error(file,line+1,errors.AesIvError)
}
// create a CTR interface
stream := cipher.NewCTR(block,iv)
cipherText := make([]byte,len(plainText))
// encrypt or decrypt
stream.XORKeyStream(cipherText,plainText)
return cipherText,nil
}
代碼我放到了gitee上:https://gitee.com/frankyu365/gocrypto
您可以查看倉庫Readme檔案或Go-包管理(管理工具對比及go mod的使用)來進行安裝
測驗代碼
iv := []byte("12345678qwertyui")
key:= []byte("12345678abcdefgh09876543alnkdjfh")
plainText := []byte("Hi,I'm lady_killer9")
cipherText,_ := aes.AesEncrypt(plainText,iv,key)
fmt.Printf("加密后:%s\n",cipherText)
decryptText,_ := aes.AesDecrypt(cipherText,iv,key)
fmt.Printf("解密后:%s\n",decryptText)

參考
《現代密碼學教程 谷利澤 楊義先等》
AES的發展史
Go標準庫-crypto/aes
Go標準庫-crypto/cipher
更多Go相關內容:Go-Golang學習總結筆記
有問題請下方評論,轉載請注明出處,并附有原文鏈接,謝謝!如有侵權,請及時聯系,如果您感覺有所識訓,自愿打賞,可選擇支付寶18833895206(小于),您的支持是我不斷更新的動力,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286901.html
標籤:其他
下一篇:移動接入技術
