Decrypt C# string encoded in GO using AES-GSM method

PHPz
Release: 2024-02-10 09:39:09
forward
1057 people have browsed it

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

php editor Xigua introduces you to a method of decrypting C# strings in GO language - AES-GSM. AES-GSM is an advanced encryption standard that combines the advantages of AES (Advanced Encryption Standard) and GSM (Global System for Mobile Communications). By using the AES-GSM method, we can effectively decrypt C# strings encoded in GO, enabling secure transmission and protection of data. This article will introduce the principles and usage steps of AES-GSM in detail to help readers easily master this encryption and decryption technology.

Question content

I have a string encrypted with aes-gcm in go and its passphrase and trying to decrypt it in c#. However, I can't find the correct way to decrypt it in c#. The error I am getting mentions that the size of the iv, the length of the block is not suitable for the c# decryption algorithm. Here are the values in go:

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

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

This is the decryption code in 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 }
Copy after login

This is the encryption code in 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) }
Copy after login

I'm trying to replicate the same decrypted login in c# so it will be able to decrypt and generate the final string.

I tried several decryption logics in c#, they can be found here:

  • https://dotnetfiddle.net/32sb5m This function uses the system.security.cryptography namespace but results in the wrong iv size.

  • https://dotnetfiddle.net/wxkuyr A modified version of the above for .net 5 will produce the same results

  • https://dotnetfiddle.net/6iftps Using bouncy castle library causes "mac check in gcm failed" error

  • https://dotnetfiddle.net/8mjs3g An alternative approach using the rfc2898derivebytes method produces an error saying "The calculated authentication token does not match the input authentication token"

Is the method currently being used correct, or is there another way to decrypt aes-gcm in c#? What can be done to bypass these errors when it comes to c#?

Solution

You are close to the last code. go Appends the authentication tag to the end of the generated ciphertext. You extracted it correctly here:

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

However, you continue to treat the array with the actual encrypted text authentication token as containing only encrypted text. To fix, extract this too:

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); }
Copy after login

The above is the detailed content of Decrypt C# string encoded in GO using AES-GSM method. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!