亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

去 AES 加密 CBC

去 AES 加密 CBC

Go
慕勒3428872 2022-08-15 16:54:51
問題我必須將函數從 移植到 ,這是使用加密。顯然,我必須得到與我得到的相同的結果C#GOAESGOC#C#代碼小提琴我準備了一個小小提琴C#using System;using System.Linq;using System.Security.Cryptography;using System.Text;public class Program{    public static void Main()    {        var query = "csharp -> golang";        var key = Encoding.UTF8.GetBytes("12345678901234567890123456789012");        var iv = Encoding.UTF8.GetBytes("1234567890123456");        using (var aes = (RijndaelManaged)RijndaelManaged.Create())        {            aes.KeySize = 256;            aes.Mode = CipherMode.CBC;            aes.Key = key;            aes.IV = iv;            using (var transform = aes.CreateEncryptor())            {                Console.WriteLine("query => " + query);                var toEncodeByte = Encoding.UTF8.GetBytes(query);                Console.WriteLine("toEncodeByte = " + ToString(toEncodeByte));                var encrypted = transform.TransformFinalBlock(toEncodeByte, 0, toEncodeByte.Length);                Console.WriteLine("encrypted = " + ToString(encrypted));            }        }    }    public static string ToString(byte[] b)    {        return "[" + String.Join(" ", b.Select(h => h.ToString())) + "]";    }}控制臺輸出query => csharp -> golangtoEncodeByte = [99 115 104 97 114 112 32 45 62 32 103 111 108 97 110 103]encrypted = [110 150 8 224 44 118 15 182 248 172 105 14 61 212 219 205 216 31 76 112 179 76 214 154 227 112 159 176 24 61 108 100]
查看完整描述

1 回答

?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

首先,兩種代碼的密文是相同的。但是,Golang 代碼中的密文轉換不正確。


在 C# 代碼中,的內容以十進制格式打印。要在 Golang 代碼中獲得等效輸出,還必須以十進制格式打印的內容,這可以通過以下方式輕松實現:byte[][]byte


fmt.Println("ciphertext ", ciphertext)

并生成以下輸出:


ciphertext  [110 150 8 224 44 118 15 182 248 172 105 14 61 212 219 205 216 31 76 112 179 76 214 154 227 112 159 176 24 61 108 100]

并且與 C# 代碼的輸出相同。


在當前代碼中,首先使用以下代碼對密文進行編碼:


encrypted = hex.EncodeToString(ciphertext)

轉換為十六進制字符串,可通過以下方式輕松驗證:


fmt.Println("encrypted (hex)", encrypted)

生成以下輸出:


encrypted (hex) 6e9608e02c760fb6f8ac690e3dd4dbcdd81f4c70b34cd69ae3709fb0183d6c64

將十六進制字符串轉換為 with 時,將進行 Utf8 編碼,該編碼將數據大小加倍,作為輸出::[]byte[]byte(encrypted)


fmt.Println("encrypted", []byte(encrypted))

在當前代碼中顯示:


encrypted [54 101 57 54 48 56 101 48 50 99 55 54 48 102 98 54 102 56 97 99 54 57 48 101 51 100 100 52 100 98 99 100 100 56 49 102 52 99 55 48 98 51 52 99 100 54 57 97 101 51 55 48 57 102 98 48 49 56 51 100 54 99 54 52]

CBC是一種塊密碼模式,即明文長度必須是塊大小的整數倍(AES為16字節)。如果不是這種情況,則必須應用填充。C# 代碼隱式使用 PKCS7 填充。這也是不滿足長度條件的明文也被處理的原因。


相反,在Golang中,必須顯式完成代碼填充,這是通過實現PKCS7填充的方法完成的。該方法的第二個參數是塊大小,對于 AES,塊大小為 16 個字節。對于此參數,實際上應該傳遞。目前,在此處傳遞,對于 AES-256,其大小為 32 字節。盡管這與當前明文長度的 C# 代碼兼容,但對于任意明文長度(例如 32 個字節)不兼容。PKCS5Padding()PKCS5Padding()aes.BlockSizelen(key)


以下代碼包含上面說明的更改和輸出:


package main


import (

    "bytes"

    "crypto/aes"

    "crypto/cipher"

    "encoding/hex"

    "fmt"

)


func main() {

    query := "csharp -> golang"

    key := []byte("12345678901234567890123456789012")

    iv := []byte("1234567890123456")


    if len(key) != 32 {

        fmt.Printf("key len must be 16. its: %v\n", len(key))

    }

    if len(iv) != 16 {

        fmt.Printf("IV len must be 16. its: %v\n", len(iv))

    }

    var encrypted string

    toEncodeByte := []byte(query)

    fmt.Println("query =>", query)

    fmt.Println("toEncodeByte = ", toEncodeByte)

    toEncodeBytePadded := PKCS5Padding(toEncodeByte, aes.BlockSize)


    // aes

    block, err := aes.NewCipher(key)

    if err != nil {

        fmt.Println("CBC Enctryping failed.")

    }

    ciphertext := make([]byte, len(toEncodeBytePadded))

    mode := cipher.NewCBCEncrypter(block, iv)

    mode.CryptBlocks(ciphertext, toEncodeBytePadded)

    encrypted = hex.EncodeToString(ciphertext)

    // end of aes

    fmt.Println("encrypted", []byte(encrypted))

    fmt.Println("encrypted (hex)", encrypted)

    fmt.Println("ciphertext", ciphertext)

    fmt.Println("aes.BlockSize", aes.BlockSize)

}


func PKCS5Padding(ciphertext []byte, blockSize int) []byte {

    padding := (blockSize - len(ciphertext)%blockSize)

    padtext := bytes.Repeat([]byte{byte(padding)}, padding)

    return append(ciphertext, padtext...)

}


查看完整回答
反對 回復 2022-08-15
  • 1 回答
  • 0 關注
  • 103 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號