Rumah >pembangunan bahagian belakang >Golang >Nyahsulit rentetan C# yang dikodkan dalam GO menggunakan kaedah AES-GSM

Nyahsulit rentetan C# yang dikodkan dalam GO menggunakan kaedah AES-GSM

PHPz
PHPzke hadapan
2024-02-10 09:39:091167semak imbas

使用 AES-GSM 方法解密在 GO 中编码的 C# 字符串

editor php Xigua memperkenalkan anda kepada kaedah menyahsulit rentetan C# dalam bahasa GO - AES-GSM. AES-GSM ialah standard penyulitan lanjutan yang menggabungkan kelebihan AES (Advanced Encryption Standard) dan GSM (Global System for Mobile Communications). Dengan menggunakan kaedah AES-GSM, kami boleh menyahsulit rentetan C# yang dikodkan dalam GO dengan berkesan, membolehkan penghantaran dan perlindungan data yang selamat. Artikel ini akan memperkenalkan prinsip dan langkah penggunaan AES-GSM secara terperinci untuk membantu pembaca menguasai teknologi penyulitan dan penyahsulitan ini dengan mudah.

Kandungan soalan

Saya mempunyai rentetan yang disulitkan dengan aes-gcm dalam go dan frasa laluannya dan cuba menyahsulitnya dalam c#. Walau bagaimanapun, saya tidak dapat mencari cara yang betul untuk menyahsulitnya dalam c#. Ralat yang saya dapat menyebut bahawa saiz iv, panjang blok tidak sesuai untuk algoritma penyahsulitan c#. Berikut adalah nilai-nilai dalam perjalanan:

aes encr/decr passphrase:  this-is-a-test-passphrase
input string:  text to encrypt hello world 123
encrypted string:  94b681ef29d9a6d7-e6fa36c4c00977de1745fc63-a1ad0481bdbeeaa02c013a2dce82520ddd762355e18f1e2f20c0ea9d001ece24e9b8216ed4b9c6a06e1ef34c953f80

kod go: https://go.dev/play/p/jn8ie61ntzw

Ini ialah kod penyahsulitan dalam go

func appdecryptimpl(passphrase, ciphertext string) string {
arr := strings.split(ciphertext, "-")
salt, _ := hex.decodestring(arr[0])
iv, _ := hex.decodestring(arr[1])
data, _ := hex.decodestring(arr[2])
key, _ := appderivekey(passphrase, salt)
b, _ := aes.newcipher(key)
aesgcm, _ := cipher.newgcm(b)
data, _ = aesgcm.open(nil, iv, data, nil)
return string(data)
}

func appderivekey(passphrase string, salt []byte) ([]byte, []byte) {
if salt == nil {
    salt = make([]byte, 8)
    rand.read(salt)
}
return pbkdf2.key([]byte(passphrase), salt, 1000, 32, sha256.new), salt
}

Ini ialah kod penyulitan dalam go

func AppEncryptImpl(passphrase string, plaintext string) string {
key, salt := appDeriveKey(passphrase, nil)
iv := make([]byte, 12)
rand.Read(iv)
b, _ := aes.NewCipher(key)
aesgcm, _ := cipher.NewGCM(b)
data := aesgcm.Seal(nil, iv, []byte(plaintext), nil)
return hex.EncodeToString(salt) + "-" + hex.EncodeToString(iv) + "-" + hex.EncodeToString(data)
}

Saya cuba meniru log masuk yang dinyahsulit yang sama dalam c# supaya ia akan dapat menyahsulit dan menjana rentetan akhir.

Saya mencuba beberapa logik penyahsulitan dalam c#, ia boleh didapati di sini:

  • https://dotnetfiddle.net/32sb5m Fungsi ini menggunakan ruang nama system.security.cryptography tetapi menyebabkan saiz iv menjadi salah.

  • https://dotnetfiddle.net/wxkuyr Versi yang diubah suai di atas untuk .net 5 akan menghasilkan keputusan yang sama

  • https://dotnetfiddle.net/6iftps Menggunakan perpustakaan bouncy castle menyebabkan ralat "mac check in gcm failed"

  • https://dotnetfiddle.net/8mjs3g Pendekatan alternatif menggunakan kaedah rfc2898derivebytes menghasilkan ralat mengatakan "Token pengesahan yang dikira tidak sepadan dengan token pengesahan input"

Adakah kaedah yang digunakan pada masa ini betul atau adakah terdapat cara lain untuk menyahsulit aes-gcm dalam c#? Apakah yang boleh dilakukan untuk memintas ralat ini apabila ia berkaitan dengan c#?

Penyelesaian

Anda hampir dengan kod terakhir. go Menambahkan teg pengesahan pada penghujung teks sifir yang dijana. Anda mengekstraknya dengan betul di sini:

// extract the tag from the encrypted byte array
byte[] tag = new byte[16];
array.copy(encrypteddata, encrypteddata.length - 16, tag, 0, 16);

Walau bagaimanapun, anda terus menganggap tatasusunan dengan teks yang disulitkan + token pengesahan sebagai hanya mengandungi teks yang disulitkan. Untuk membetulkannya, ekstraknya juga:

public static void Main() {
    // This is the encrypted string that you provided
    string encryptedString = "a6c0952b78967559-2953e738b9b005028bf4f6c0-7b8464d1ed75bc38b4503f6c8d25d6bfc22a19cc1a8a92bc6faa1ed6cd837b97072bc8e16fd95b6cfca67fccbad8fc";

    // This is the passphrase that you provided
    string passphrase = "this-is-a-test-passphrase";

    string[] splitStrs = encryptedString.Split('-');

    byte[] salt = Convert.FromHexString(splitStrs[0]);
    byte[] iv = Convert.FromHexString(splitStrs[1]);
    // this is encrypted data + tag
    byte[] encryptedDataWithTag = Convert.FromHexString(splitStrs[2]);
    // Extract the tag from the encrypted byte array
    byte[] tag = new byte[16];
    // But also extract actual encrypted data
    byte[] encryptedData = new byte[encryptedDataWithTag.Length - 16];
    Array.Copy(encryptedDataWithTag, 0, encryptedData, 0, encryptedData.Length);
    Array.Copy(encryptedDataWithTag, encryptedDataWithTag.Length - 16, tag, 0, 16);
    byte[] key = new Rfc2898DeriveBytes(passphrase, salt, 1000, HashAlgorithmName.SHA256).GetBytes(32);
    // Create an AesGcm object
    AesGcm aesGcm = new AesGcm(key);
    int textLength = encryptedData.Length;
    // Decrypt the ciphertext
    byte[] plaintext = new byte[textLength];
    aesGcm.Decrypt(iv, encryptedData, tag, plaintext);
    // Convert the plaintext to a string and print it
    string decryptedString = Encoding.UTF8.GetString(plaintext);
    Console.WriteLine(decryptedString);
}

Atas ialah kandungan terperinci Nyahsulit rentetan C# yang dikodkan dalam GO menggunakan kaedah AES-GSM. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam