日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

golang中的对称加密

發布時間:2025/6/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang中的对称加密 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概念

  • 按位異或

    • 第一步需要將數據轉換為二進制

    • 按位異或操作符: ^

    • 兩個標志位進行按位異或操作:

      • 相同為0, 不同為1
    • 舉例:

      1 0 0 0 ----> 8 1 0 1 1 ----> 11 -----------------------按位異或一次 0 0 1 1 ----> 3 1 0 1 1 ----> 11 -----------------------按位異或兩側 1 0 0 0 -----> 8 ================================= a = 8 b = 11 a 和 b按位異或1次 ==> 加密 得到的結果再次和 b 按位異或 ===> 解密
  • ECB - Electronic Code Book, 電子密碼本模式

    • 特點: 簡單, 效率高, 密文有規律, 容易被破解
    • 最后一個明文分組必須要填充
      • des/3des -> 最后一個分組填充滿8字節
      • aes -> 最后一個分組填充滿16字節
    • 不需要初始化向量
  • CBC - Cipher Block Chaining, 密碼塊鏈模式

    • 特點: 密文沒有規律, 經常使用的加密方式
    • 最后一個明文分組需要填充
      • des/3des -> 最后一個分組填充滿8字節
      • aes -> 最后一個分組填充滿16字節
    • 需要一個初始化向量 - 一個數組
      • 數組的長度: 與明文分組相等
      • 數據來源: 負責加密的人的提供的
      • 加解密使用的初始化向量值必須相同
  • CFB - Cipher FeedBack, 密文反饋模式

    • 特點: 密文沒有規律, 明文分組是和一個數據流進行的按位異或操作, 最終生成了密文
    • 需要一個初始化向量 - 一個數組
      • 數組的長度: 與明文分組相等
      • 數據來源: 負責加密的人的提供的
      • 加解密使用的初始化向量值必須相同
    • 不需要填充
  • OFB - Output-Feedback, 輸出反饋模式

    • 特點: 密文沒有規律, 明文分組是和一個數據流進行的按位異或操作, 最終生成了密文
    • 需要一個初始化向量 - 一個數組
      • 數組的長度: 與明文分組相等
      • 數據來源: 負責加密的人的提供的
      • 加解密使用的初始化向量值必須相同
    • 不需要填充
  • CTR - CounTeR, 計數器模式

    • 特點: 密文沒有規律, 明文分組是和一個數據流進行的按位異或操作, 最終生成了密文
    • 不需要初始化向量
      • go接口中的iv可以理解為隨機數種子, iv的長度 == 明文分組的長度
    • 不需要填充
  • 最后一個明文分組的填充

    • 使用cbc, ecb需要填充
      • 要求:
        • 明文分組中進行了填充, 然后加密
        • 解密密文得到明文, 需要把填充的字節刪除
    • 使用 ofb, cfb, ctr不需要填充
  • 初始化向量 - IV

    • ecb, ctr模式不需要初始化向量
    • cbc, ofc, cfb需要初始化向量
      • 初始化向量的長度
        • des/3des -> 8字節
        • aes -> 16字節
      • 加解密使用的初始化向量相同
  • 實現

  • des

  • 3des

  • aes

  • # 加密流程:1. 創建一個底層使用des/3des/aes的密碼接口"crypto/des"func NewCipher(key []byte) (cipher.Block, error) # -- desfunc NewTripleDESCipher(key []byte) (cipher.Block, error) # -- 3des"crypto/aes"func NewCipher(key []byte) (cipher.Block, error) # == aes2. 如果使用的是cbc/ecb分組模式需要對明文分組進行填充3. 創建一個密碼分組模式的接口對象- cbcfunc NewCBCEncrypter(b Block, iv []byte) BlockMode # 加密- cfbfunc NewCFBEncrypter(block Block, iv []byte) Stream # 加密- ofb- ctr4. 加密, 得到密文 import ("bytes""crypto/aes""crypto/cipher""crypto/des""fmt" )//des的CBC加密 //編寫填充函數,如果最后一個分組字節不夠,填充 //...字節數剛好合適,添加一個新分組 //填充個的字節的值==缺少的字節數 func paddingLastGroup(plainText []byte, bloclsize int) []byte {//1. 求出最后一個組中剩余的字節數padNum := bloclsize - (len(plainText) % bloclsize)//2. 創建一個新的切片, 長度==padNum, 每個字節值byte(padNum)char := []byte{byte(padNum)} //切片長度是1//切片創建并且重復多少次newPlain := bytes.Repeat(char, padNum)//3. newPlain數組追加到原始明文的后面newText := append(plainText, newPlain...)return newText }//去掉填充的數據 func unPaddingLastGrooup(plainText []byte) []byte {//1. 拿去切片中的最后一個字節length := len(plainText)lastChar := plainText[length-1]number := int(lastChar) //尾部填充的字節數return plainText[:length-number] }//des加密 func desEncrypt(plainText, key []byte) []byte {//1. 建一個底層使用des的密碼接口block, err := des.NewCipher(key)if err != nil {panic(err)}//2. 明文填充newText := paddingLastGroup(plainText, block.BlockSize())//3. 創建一個使用cbc分組接口iv := []byte("12345678") //8字節blockMode := cipher.NewCBCEncrypter(block, iv)//4. 加密cipherText := make([]byte, len(newText))blockMode.CryptBlocks(cipherText, newText)//也可以這樣,他加密過會把newText的值覆蓋過去,然后返回newText就可以//blockMode.CryptBlocks(newText, newText)return cipherText }// des解密 func desDecrypt(cipherText, key []byte) []byte {// 1. 建一個底層使用des的密碼接口block, err := des.NewCipher(key)if err != nil {panic(err)}// 2. 創建一個使用cbc模式解密的接口iv := []byte("12345678")blockMode := cipher.NewCBCDecrypter(block, iv)// 3. 解密blockMode.CryptBlocks(cipherText, cipherText)// 4. cipherText現在存儲的是明文, 需要刪除加密時候填充的尾部數據plainText := unPaddingLastGrooup(cipherText)return plainText }// aes加密, 分組模式ctr func aesEncrypt(plainText, key []byte) []byte {// 1. 建一個底層使用aes的密碼接口block, err := aes.NewCipher(key)if err != nil {panic(err)}// 2. 創建一個使用ctr分組接口iv := []byte("12345678WHZdefgh")stream := cipher.NewCTR(block, iv)// 4. 加密cipherText := make([]byte, len(plainText))stream.XORKeyStream(cipherText, plainText)return cipherText }// des解密 func aesDecrypt(cipherText, key []byte) []byte {// 1. 建一個底層使用des的密碼接口block, err := aes.NewCipher(key)if err != nil {panic(err)}// 2. 創建一個使用ctr模式解密的接口iv := []byte("12345678WHZdefgh")stream := cipher.NewCTR(block, iv)// 3. 解密stream.XORKeyStream(cipherText, cipherText)return cipherText }//測試文件 func main() {fmt.Println("des 加解密")key := []byte("1234abEd")src := []byte("特點: 密文沒有規律, 明文分組是和一個數據流進行的按位異或操作, 最終生成了密文")cipherText := desEncrypt(src, key)plainText := desDecrypt(cipherText, key)fmt.Printf("解密之后的數據: %s\n", string(plainText))fmt.Println("aes 加解密 ctr模式 ... ")key1 := []byte("1234abdd12345678")cipherText = aesEncrypt(src, key1)plainText = aesDecrypt(cipherText, key1)fmt.Printf("解密之后的數據: %s\n", string(plainText)) }

    總結

    • 對稱加密中的公開的加密算法

      • des

        • 分組長度: 8字節
        • 秘鑰長度: 8字節
      • 3des

        • 分組長度: 8字節
        • 秘鑰長度: 24byte
      • aes

        • 分組長度: 16字節
        • 秘鑰長度: 16字節, 24字節, 32字節
          • 在go的api中只能使用16字節
      • 對稱加密的分組模式

        • EBC - 不推薦使用

        • CBC - 常用的方式

          • 準備的數據:

            • 初始化向量iv - 字符數組
            • 長度 == 明文分組長度
            • 加解密初始化向量值必須相同
            • 秘鑰
              • 根據加密算法定

          ===========================

        • OFB - 不推薦使用

        • CFB - 不推薦使用

        • CTR - 推薦使用, 效率最高

    總結

    以上是生活随笔為你收集整理的golang中的对称加密的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。