簡體   English   中英

使用AES-GSM方法解密GO中編碼的C#中的字符串

[英]Decrypting a string in C# that was encoded in GO using the AES-GSM method

我有一個在 Go 中用 AES-GCM 加密的字符串,連同它的密碼短語,我試圖在 C# 中解密它。但是,我無法在 C# 中找到正確的方法來解密它。錯誤我我越來越提到 IV 的大小,塊不是 C# 解密算法的正確長度。 以下是來自 Go 的值:

AES encr/decr 密碼:這是一個測試密碼

輸入字符串:用於加密 hello world 123 的文本

加密字符串:94b681ef29d9a6d7-e6fa36c4c00977de1745fc63-a1ad0481bdbeeaa02c013a2dce82520ddd762355e18f1e2f20c0ea9d001ece24e9b8216ed4b9c6a06e1ef34c95

GO 代碼: https://go.dev/play/p/jN8Ie61Ntzw

這是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
}

這是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)
}

我正在嘗試在 C# 中復制相同的解密登錄名,因此它將能夠解密並生成最終字符串。

我在 C# 中嘗試了幾種解密邏輯,它們可以在這里找到:

當前使用的方法是正確的方法還是有另一種方法可以在 C# 中解密 AES-GCM? 當涉及到 C# 時,如何繞過這些錯誤?

您已接近最后一個代碼。 Go 將認證標簽附加到生成的密文末尾。 你在這里正確地提取它:

// Extract the tag from the encrypted byte array
byte[] tag = new byte[16];
Array.Copy(encryptedData, encryptedData.Length - 16, tag, 0, 16);

但是隨后您繼續將具有實際加密文本 + auth 標記的數組視為僅包含加密文本。 要修復,還要提取它:

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM