最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具

 更新時(shí)間:2022年05月13日 11:33:16   作者:iqsing  
這篇文章主要為大家詳細(xì)介紹了如何利用Golang制作一個(gè)AES加密解密工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

本文包含如下兩個(gè)內(nèi)容:

AES加密介紹及實(shí)現(xiàn)原理

Go實(shí)現(xiàn)AES加密和解密工具

AES加密介紹及實(shí)現(xiàn)原理

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用在哪里

如果你正在瀏覽本文,那么你就在使用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ì)使用到)。

AES加密是如何實(shí)現(xiàn)的

參考:

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-128128位(16字節(jié))10128位(16字節(jié))
AES-192192位(24字節(jié))12128位(16字節(jié))
AES-256256位(32字節(jié))14128位(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)行反向加密。

AES加密模式

ECB

在上面加密過(guò)程中每一個(gè)明文塊都是獨(dú)立進(jìn)行加密的,簡(jiǎn)單且高效,但是如果一個(gè)段數(shù)據(jù)存在相關(guān)的明文塊,則加密后的密文也會(huì)相同,對(duì)安全性也有一定影響。

CBC

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

Go實(shí)現(xiàn)AES加密工具scode

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

完整代碼:source

到此這篇關(guān)于通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具的文章就介紹到這了,更多相關(guān)Golang AES加密解密工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang pipe在不同場(chǎng)景下遠(yuǎn)程交互

    Golang pipe在不同場(chǎng)景下遠(yuǎn)程交互

    這篇文章主要介紹了Golang pipe在不同場(chǎng)景下遠(yuǎn)程交互,pipe實(shí)現(xiàn)從一個(gè)進(jìn)程重定向至另一個(gè)進(jìn)程,它是雙向數(shù)據(jù)通道,用于實(shí)現(xiàn)進(jìn)行間通信
    2023-03-03
  • golang?gorm模型結(jié)構(gòu)體的定義示例

    golang?gorm模型結(jié)構(gòu)體的定義示例

    這篇文章主要為大家介紹了golang?gorm模型結(jié)構(gòu)體的定義示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Mac OS系統(tǒng)安裝golang教程

    Mac OS系統(tǒng)安裝golang教程

    這篇文章主要介紹了Mac OS系統(tǒng)安裝golang教程,本文還同時(shí)介紹了Sublime Text開(kāi)發(fā)工具的配置,需要的朋友可以參考下
    2015-01-01
  • go語(yǔ)言執(zhí)行windows下命令行的方法

    go語(yǔ)言執(zhí)行windows下命令行的方法

    這篇文章主要介紹了go語(yǔ)言執(zhí)行windows下命令行的方法,實(shí)例分析了Go語(yǔ)言操作windows下命令行的技巧,需要的朋友可以參考下
    2015-03-03
  • Go Java算法之累加數(shù)示例詳解

    Go Java算法之累加數(shù)示例詳解

    這篇文章主要為大家介紹了Go Java算法之累加數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • golang根據(jù)URL獲取文件名的示例代碼

    golang根據(jù)URL獲取文件名的示例代碼

    這篇文章主要為大家詳細(xì)介紹了golang根據(jù)URL獲取文件名,文中的示例代碼講解詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • go語(yǔ)言中的return語(yǔ)句

    go語(yǔ)言中的return語(yǔ)句

    這篇文章主要介紹了go語(yǔ)言中的return語(yǔ)句,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-05-05
  • go語(yǔ)言編程之select信道處理示例詳解

    go語(yǔ)言編程之select信道處理示例詳解

    這篇文章主要為大家介紹了go語(yǔ)言編程之select信道處理示例詳解,<BR>有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Windows上安裝Go并配置環(huán)境變量(圖文步驟)

    Windows上安裝Go并配置環(huán)境變量(圖文步驟)

    開(kāi)始使用Go創(chuàng)建應(yīng)用程序之前,需要設(shè)置開(kāi)發(fā)環(huán)境,本文主要介紹了Windows上安裝Go并配置環(huán)境變量,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • golang中defer的基本使用教程

    golang中defer的基本使用教程

    go語(yǔ)言中defer可以完成延遲功能,當(dāng)前函數(shù)執(zhí)行完成后再執(zhí)行defer的代碼塊,下面這篇文章主要給大家介紹了關(guān)于golang中defer基本使用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06

最新評(píng)論

张北县| 曲阳县| 商都县| 高清| 舟山市| 织金县| 肃南| 江口县| 宣城市| 福清市| 怀安县| 新宁县| 东阳市| 碌曲县| 克拉玛依市| 牙克石市| 军事| 舒兰市| 西林县| 宝丰县| 噶尔县| 浦城县| 勃利县| 来安县| 阳东县| 察隅县| 嘉善县| 图们市| 诸城市| 巴彦淖尔市| 宝鸡市| 砚山县| 新闻| 城口县| 安图县| 永福县| 蒙阴县| 虞城县| 义乌市| 错那县| 忻城县|