您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“怎么通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“怎么通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具”吧!
AES( advanced encryption standard)使用相同密鑰進(jìn)行加密和解密,也就是對(duì)稱(chēng)加密。其他的對(duì)稱(chēng)加密如DES,由于DES密鑰長(zhǎng)度只有56位如今的算力甚至可以在5分鐘內(nèi)破解,而AES最高級(jí)別達(dá)到了256位密鑰長(zhǎng)度,如果采用窮舉法,目前來(lái)看AES是一種”無(wú)法“被破解的加密存在。
如果你正在瀏覽本文,那么你就在使用AES(https協(xié)議中一部分使用了對(duì)稱(chēng)加密)。
綠色上網(wǎng):通過(guò)加密安全地連接到另一臺(tái)搬石頭砸腳的服務(wù)器。
無(wú)線(xiàn)網(wǎng)絡(luò)WIFI:和WAP2一起使用。
應(yīng)用程序:wechat、JD、Alipay等使用 AES 加密照片和消息或支付信息。
存檔和壓縮工具:7z、WinZip 和 RAR。
操作系統(tǒng)組件:一些操作系統(tǒng)組件(如文件系統(tǒng))使用高級(jí)加密標(biāo)準(zhǔn)來(lái)確保安全性。
編程語(yǔ)言庫(kù): Go、Python 和 C++ 等編碼庫(kù)實(shí)現(xiàn)了的AES加密(等會(huì)使用到)。
參考:
what-is-the-aes-algorithm?
What is AES encryption and how does it work?
Block cipher mode of operation
從宏觀上來(lái)看AES加密過(guò)程中的一輪(根據(jù)不同的密鑰長(zhǎng)度,輪數(shù)不一樣,下面會(huì)說(shuō)到)如下:
1.數(shù)據(jù)分塊
首先把明文按照128bit拆分成若干個(gè)明文塊(圖上黃色塊),一個(gè)字節(jié)包含 8 位,布局為 4×4矩陣(上圖黃色部分),對(duì)最后一塊填充至128bit,填充方式有PKCS7Padding(采用)/PKCS5Padding/ZeroPadding,無(wú)論咋填充最后解密時(shí)都要去除這些多余的填充。
2.密鑰擴(kuò)展
AES通過(guò)Rijndael's key schedule 將密鑰被擴(kuò)展為 (n+1) 個(gè)密鑰,其中 n 是加密過(guò)程中要遵循的輪數(shù)。AES每個(gè)標(biāo)準(zhǔn)規(guī)定了所要加密的輪數(shù),對(duì)于128位密鑰,輪數(shù)是 10,要生成的密鑰個(gè)數(shù)為 10+1,總共 11 個(gè)密鑰。
標(biāo)準(zhǔn) | 密鑰長(zhǎng)度 | 輪數(shù) | 分組長(zhǎng)度 |
---|---|---|---|
AES-128 | 128位(16字節(jié)) | 10 | 128位(16字節(jié)) |
AES-192 | 192位(24字節(jié)) | 12 | 128位(16字節(jié)) |
AES-256 | 256位(32字節(jié)) | 14 | 128位(16字節(jié)) |
每一輪所要做的包括:字節(jié)替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)、加輪密鑰(AddRoundKey)
3.字節(jié)替代(SubBytes)
每輪開(kāi)始,首先進(jìn)行SubBytes,字節(jié)根據(jù)預(yù)定義的 Rijndael S-box(可以簡(jiǎn)單認(rèn)為是一個(gè)轉(zhuǎn)換表)規(guī)定的規(guī)則進(jìn)行替換。對(duì)a[i,j]中的每個(gè)字節(jié)進(jìn)行一次轉(zhuǎn)換后得到b[i,j]
4.行移位(ShiftRows)
對(duì)上一步得到矩陣進(jìn)行ShiftRows,第一行不變,第二行移動(dòng)1位,第三行2位,第四行3位。
5.列混淆(MixColumns)
再對(duì)矩陣的每一列和修補(bǔ)矩陣fixed matrix的二維常量數(shù)組做矩陣相乘,得到對(duì)應(yīng)的輸出列。
6.加輪密鑰(AddRoundKey)
先將擴(kuò)展密鑰Kn排列成4×4矩陣,然后讓輸入數(shù)組的每一個(gè)字節(jié)a[i,j]與密鑰對(duì)應(yīng)位置的字節(jié)k[i,j]異或一次,得到輸出b[i,j]。最后一輪不參與AddRoundKey
經(jīng)過(guò)如上的10輪操作之后,得到了一個(gè)明文塊的加密字符。解密則進(jìn)行反向加密。
ECB
在上面加密過(guò)程中每一個(gè)明文塊都是獨(dú)立進(jìn)行加密的,簡(jiǎn)單且高效,但是如果一個(gè)段數(shù)據(jù)存在相關(guān)的明文塊,則加密后的密文也會(huì)相同,對(duì)安全性也有一定影響。
CBC
CBC加密模式如下圖所示,初始向量IV和明文異或,每個(gè)塊的密文作為后續(xù)塊的“向量”,讓每一個(gè)密文獨(dú)一無(wú)二。我們待會(huì)采用這種模式。
ok,上面大致了解AES加密是如何工作起來(lái)的,接下來(lái)通過(guò)Go中的crypto/aes和crypto/cipher包實(shí)現(xiàn)的AES加密解密工具。
PKCS7Padding將待補(bǔ)足字節(jié)數(shù)作為填充的字節(jié)
// pkcs7Padding 填充 func pkcs7Padding(data []byte, blockSize int) []byte { //判斷缺少幾位長(zhǎng)度。最少1,最多 blockSize padding := blockSize - len(data)%blockSize //補(bǔ)足位數(shù)。把切片[]byte{byte(padding)}復(fù)制padding個(gè) padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(data, padText...) } // pkcs7UnPadding 移除 func pkcs7UnPadding(data []byte) ([]byte, error) { length := len(data) if length == 0 { return nil, errors.New("加密字符串錯(cuò)誤!") } //獲取填充的個(gè)數(shù) unPadding := int(data[length-1]) return data[:(length - unPadding)], nil }
使用 cipher的CBC模式對(duì)block加密和解密
// AesEncrypt 加密 func AesEncrypt(data []byte, key []byte) ([]byte, error) { // NewCipher creates and returns a new cipher.Block. The key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. block, err := aes.NewCipher(key) if err != nil { return nil, err } //判斷加密快的大小 blockSize := block.BlockSize() //填充 encryptBytes := pkcs7Padding(data, blockSize) //初始化加密數(shù)據(jù)接收切片 crypted := make([]byte, len(encryptBytes)) //使用cbc加密模式 blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) //執(zhí)行加密 blockMode.CryptBlocks(crypted, encryptBytes) return crypted, nil } // AesDecrypt 解密 func AesDecrypt(data []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } //獲取塊的大小 blockSize := block.BlockSize() //使用cbc blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) //初始化解密數(shù)據(jù)接收切片 crypted := make([]byte, len(data)) //執(zhí)行解密 blockMode.CryptBlocks(crypted, data) //去填充 crypted, err = pkcs7UnPadding(crypted) if err != nil { return nil, err } return crypted, nil }
循環(huán)從文件中讀取100mb源數(shù)據(jù)用于加密后將密文寫(xiě)入文件,解密則讀取密文解密后將源數(shù)據(jù)寫(xiě)入文件。
func EncryptFile(fileName string) (err error) { f, err := os.Open(fileName) if err != nil { fmt.Println("未找到文件") return } defer f.Close() fInfo, _ := f.Stat() fLen := fInfo.Size() fmt.Println("待處理文件大小:", fLen) maxLen := 1024 * 1024 * 100 //100mb 每 100mb 進(jìn)行加密一次 var forNum int64 = 0 getLen := fLen if fLen > int64(maxLen) { getLen = int64(maxLen) forNum = fLen / int64(maxLen) fmt.Println("需要加密次數(shù):", forNum+1) } // encryptd to file ff, err := os.OpenFile("en_"+fileName, os.O_RDWR|os.O_CREATE, 0666) if err != nil { fmt.Println("文件寫(xiě)入錯(cuò)誤") return err } defer ff.Close() //循環(huán)加密,并寫(xiě)入文件 for i := 0; i < int(forNum+1); i++ { a := make([]byte, getLen) n, err := f.Read(a) if err != nil { fmt.Println("文件讀取錯(cuò)誤") return err } getByte, err := EncryptByAes(a[:n]) if err != nil { fmt.Println("加密錯(cuò)誤") return err } getBytes := append([]byte(getByte), []byte("\n")...) //寫(xiě)入 buf := bufio.NewWriter(ff) buf.WriteString(string(getBytes[:])) buf.Flush() } ffInfo, _ := ff.Stat() fmt.Printf("加密后文件為:%s,文件大小為:%v Byte \n", ffInfo.Name(), ffInfo.Size()) return nil }
參考:Golang實(shí)現(xiàn)AES加密和解密的示例代碼
通過(guò)cobra添加命令后,創(chuàng)建命令的匿名函數(shù)
func(cmd *cobra.Command, args []string) { copy(PwdKey, readPass()) Pwd := []byte("csgo!gogo") if ByteSliceEqual(PwdKey, Pwd) { //16字節(jié)key PwdKey = append(PwdKey, 7, 3, 5, 5, 6, 0, 8) if err := DecryptFile(args[0]); err != nil { panic(err) } } else { fmt.Println("密碼錯(cuò)誤") os.Exit(1) } }
使用方式看起來(lái)如下:
scode工具包含2個(gè)命令encode和decode,解密文件需要密碼。
# ./scode encode xpower.tar.gz 待處理文件大小: 3397 加密后文件為:en_xpower.tar.gz,文件大小為:4545 Byte # ./scode decode en_xpower.tar.gz ENTER PASSWORD: 密碼錯(cuò)誤 # ./scode decode en_xpower.tar.gz ENTER PASSWORD: 待處理文件大小: 4545 解密后文件為:de_en_xpower.tar.gz,文件大小為:3159 Byte
到此,相信大家對(duì)“怎么通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。