Проблема
Мне нужно перенести функцию с C#
на GO
, которая использует шифрование AES
. очевидно, я должен получить тот же результат с GO
, что и с C#
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 -> golang
toEncodeByte = [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]
GO
кодовая скрипка
я приготовил небольшую скрипку с GO
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, len(key))
// 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))
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := (blockSize - len(ciphertext)%blockSize)
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
консольный вывод
query => csharp -> golang
toEncodeByte = [99 115 104 97 114 112 32 45 62 32 103 111 108 97 110 103]
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]
Резюме
Я заметил, что в C#
входные данные не обязательно должны быть того же размера, что и block
.
В GO
это, кажется, не работает без заполнения (поэтому я добавил заполнение в GO
code), но результат отличается.
Решение для получения результата equal
было бы отличным