中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么通過Golang編寫一個AES加密解密工具

發布時間:2022-05-13 13:44:23 來源:億速云 閱讀:534 作者:iii 欄目:開發技術

本篇內容主要講解“怎么通過Golang編寫一個AES加密解密工具”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么通過Golang編寫一個AES加密解密工具”吧!

AES加密介紹及實現原理

AES( advanced encryption standard)使用相同密鑰進行加密和解密,也就是對稱加密。其他的對稱加密如DES,由于DES密鑰長度只有56位如今的算力甚至可以在5分鐘內破解,而AES最高級別達到了256位密鑰長度,如果采用窮舉法,目前來看AES是一種”無法“被破解的加密存在。

怎么通過Golang編寫一個AES加密解密工具

AES用在哪里

如果你正在瀏覽本文,那么你就在使用AES(https協議中一部分使用了對稱加密)。

  • 綠色上網:通過加密安全地連接到另一臺搬石頭砸腳的服務器

  • 無線網絡WIFI:和WAP2一起使用。

  • 應用程序:wechat、JD、Alipay等使用 AES 加密照片和消息或支付信息。

  • 存檔和壓縮工具:7z、WinZip 和 RAR。

  • 操作系統組件:一些操作系統組件(如文件系統)使用高級加密標準來確保安全性。

  • 編程語言庫: Go、Python 和 C++ 等編碼庫實現了的AES加密(等會使用到)。

AES加密是如何實現的

參考:

what-is-the-aes-algorithm?

What is AES encryption and how does it work?

Block cipher mode of operation

從宏觀上來看AES加密過程中的一輪(根據不同的密鑰長度,輪數不一樣,下面會說到)如下:

怎么通過Golang編寫一個AES加密解密工具

1.數據分塊

首先把明文按照128bit拆分成若干個明文塊(圖上黃色塊),一個字節包含 8 位,布局為 4×4矩陣(上圖黃色部分),對最后一塊填充至128bit,填充方式有PKCS7Padding(采用)/PKCS5Padding/ZeroPadding,無論咋填充最后解密時都要去除這些多余的填充。

2.密鑰擴展

AES通過Rijndael's key schedule 將密鑰被擴展為 (n+1) 個密鑰,其中 n 是加密過程中要遵循的輪數。AES每個標準規定了所要加密的輪數,對于128位密鑰,輪數是 10,要生成的密鑰個數為 10+1,總共 11 個密鑰。

標準密鑰長度輪數分組長度
AES-128128位(16字節)10128位(16字節)
AES-192192位(24字節)12128位(16字節)
AES-256256位(32字節)14128位(16字節)

每一輪所要做的包括:字節替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)、加輪密鑰(AddRoundKey)

怎么通過Golang編寫一個AES加密解密工具

3.字節替代(SubBytes)

每輪開始,首先進行SubBytes,字節根據預定義的 Rijndael S-box(可以簡單認為是一個轉換表)規定的規則進行替換。對a[i,j]中的每個字節進行一次轉換后得到b[i,j]

怎么通過Golang編寫一個AES加密解密工具

4.行移位(ShiftRows)

對上一步得到矩陣進行ShiftRows,第一行不變,第二行移動1位,第三行2位,第四行3位。

怎么通過Golang編寫一個AES加密解密工具

5.列混淆(MixColumns)

再對矩陣的每一列和修補矩陣fixed matrix的二維常量數組做矩陣相乘,得到對應的輸出列。

怎么通過Golang編寫一個AES加密解密工具

6.加輪密鑰(AddRoundKey)

先將擴展密鑰Kn排列成4×4矩陣,然后讓輸入數組的每一個字節a[i,j]與密鑰對應位置的字節k[i,j]異或一次,得到輸出b[i,j]。最后一輪不參與AddRoundKey

怎么通過Golang編寫一個AES加密解密工具

經過如上的10輪操作之后,得到了一個明文塊的加密字符。解密則進行反向加密。

AES加密模式

ECB

在上面加密過程中每一個明文塊都是獨立進行加密的,簡單且高效,但是如果一個段數據存在相關的明文塊,則加密后的密文也會相同,對安全性也有一定影響。

怎么通過Golang編寫一個AES加密解密工具

CBC

CBC加密模式如下圖所示,初始向量IV和明文異或,每個塊的密文作為后續塊的“向量”,讓每一個密文獨一無二。我們待會采用這種模式。

怎么通過Golang編寫一個AES加密解密工具

Go實現AES加密工具scode

ok,上面大致了解AES加密是如何工作起來的,接下來通過Go中的crypto/aes和crypto/cipher包實現的AES加密解密工具。

PKCS7Padding將待補足字節數作為填充的字節

// pkcs7Padding 填充
func pkcs7Padding(data []byte, blockSize int) []byte {
    //判斷缺少幾位長度。最少1,最多 blockSize
    padding := blockSize - len(data)%blockSize
    //補足位數。把切片[]byte{byte(padding)}復制padding個
    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("加密字符串錯誤!")
    }
    //獲取填充的個數
    unPadding := int(data[length-1])
    return data[:(length - unPadding)], nil
}

使用 cipher的CBC模式對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)
    //初始化加密數據接收切片
    crypted := make([]byte, len(encryptBytes))
    //使用cbc加密模式
    blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
    //執行加密
    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])
    //初始化解密數據接收切片
    crypted := make([]byte, len(data))
    //執行解密
    blockMode.CryptBlocks(crypted, data)
    //去填充
    crypted, err = pkcs7UnPadding(crypted)
    if err != nil {
        return nil, err
    }
    return crypted, nil
}

循環從文件中讀取100mb源數據用于加密后將密文寫入文件,解密則讀取密文解密后將源數據寫入文件。

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 進行加密一次
    var forNum int64 = 0
    getLen := fLen

    if fLen > int64(maxLen) {
        getLen = int64(maxLen)
        forNum = fLen / int64(maxLen)
        fmt.Println("需要加密次數:", forNum+1)
    }
    // encryptd to file
    ff, err := os.OpenFile("en_"+fileName, os.O_RDWR|os.O_CREATE, 0666)
    if err != nil {
        fmt.Println("文件寫入錯誤")
        return err
    }
    defer ff.Close()
    //循環加密,并寫入文件
    for i := 0; i < int(forNum+1); i++ {
        a := make([]byte, getLen)
        n, err := f.Read(a)
        if err != nil {
            fmt.Println("文件讀取錯誤")
            return err
        }
        getByte, err := EncryptByAes(a[:n])
        if err != nil {
            fmt.Println("加密錯誤")
            return err
        }
        getBytes := append([]byte(getByte), []byte("\n")...)
        //寫入
        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實現AES加密和解密的示例代碼

通過cobra添加命令后,創建命令的匿名函數

func(cmd *cobra.Command, args []string) {
    copy(PwdKey, readPass())
    Pwd := []byte("csgo!gogo")
    if ByteSliceEqual(PwdKey, Pwd) {
        //16字節key
        PwdKey = append(PwdKey, 7, 3, 5, 5, 6, 0, 8)
        if err := DecryptFile(args[0]); err != nil {
            panic(err)
        }
    } else {
        fmt.Println("密碼錯誤")
        os.Exit(1)
    }
}

使用方式看起來如下:

scode工具包含2個命令encode和decode,解密文件需要密碼。

# ./scode  encode xpower.tar.gz
待處理文件大小: 3397
加密后文件為:en_xpower.tar.gz,文件大小為:4545 Byte

# ./scode  decode en_xpower.tar.gz
ENTER PASSWORD: 
密碼錯誤

# ./scode  decode en_xpower.tar.gz
ENTER PASSWORD: 
待處理文件大小: 4545
解密后文件為:de_en_xpower.tar.gz,文件大小為:3159 Byte

到此,相信大家對“怎么通過Golang編寫一個AES加密解密工具”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

渝北区| 高平市| 乐亭县| 屯昌县| 合作市| 拉萨市| 常熟市| 青海省| 阿荣旗| 永福县| 城步| 盐山县| 新蔡县| 拜城县| 锡林浩特市| 合肥市| 洞口县| 黔江区| 荔波县| 汶川县| 邻水| 宜春市| 海盐县| 浦江县| 肥乡县| 凯里市| 汕尾市| 北宁市| 三穗县| 三明市| 毕节市| 呼伦贝尔市| 乌兰县| 婺源县| 定结县| 开化县| 延长县| 公主岭市| 嘉鱼县| 麻栗坡县| 霍州市|