gpt4 book ai didi

c# - 解密由 pgcrypto 加密的数据(在 C# 中)

转载 作者:行者123 更新时间:2023-11-29 11:44:51 24 4
gpt4 key购买 nike

我正在尝试解密使用 pgcrypto 加密的数据。我没有使用 IV,因为它只是一个测试,但我无法在 C# 中解密数据。

在 PostGres 中加密:

enc_key := '\\xAACE38F289EC3EA209B48D';

-- Time insertions
ts_start := clock_timestamp();
FOR i IN 1..num_loops LOOP

-- The text to insert and its key
plaintext := 'Number: ' || i;
plaintext_pk := gen_random_uuid();
plaintext_pk_as_text := plaintext_pk::text;

-- The ref entries
user_pk := gen_random_uuid();
user_ref_pk := encrypt(plaintext_pk_as_text::bytea, enc_key, 'aes');

-- Add the enries
INSERT INTO "Text" VALUES(plaintext_pk, plaintext);
INSERT INTO "User" VALUES(user_ref_pk, user_pk);

END LOOP;
ts_end := clock_timestamp();
elapsed_raw := cast(extract(epoch from (ts_end - ts_start)) as numeric(18,3));

在 C# 中解密:

// The decryption key
byte[] enc_key = new byte[] { 0xAA, 0xCE, 0x38, 0xF2, 0x89, 0xEC, 0x3E, 0xA2, 0x09, 0xB4, 0x8D,
0x00, 0x00, 0x00, 0x00, 0x00 };

public static string AESDecryptByteArray(byte [] encoded_data, byte [] key)
{
string result = "";
byte [] result_ba = new byte[64];

using (Aes myAes = Aes.Create())
{
if (myAes == null)
{
throw new Exception("Failed to create AES object.");
}

myAes.Key = key;
myAes.Mode = CipherMode.CBC;
myAes.Padding = PaddingMode.PKCS7;

MemoryStream streamMem = new MemoryStream(encoded_data);

byte[] IV = new byte[16];
// streamMem.Read(IV, 0, 16);
for (int i = 0; i < 16; ++i )
{
IV[i] = 0;
}
myAes.IV = IV;

int iNumBytes = 0;
var decryptor = myAes.CreateDecryptor();
using (CryptoStream streamCrypt = new CryptoStream(streamMem, decryptor, CryptoStreamMode.Read))
{
iNumBytes = streamCrypt.Read(result_ba, 0, 48);
}

result = System.Text.Encoding.ASCII.GetString(result_ba);
}

return result;

} // AESDecryptByteArray

我从其中一行复制了生成的加密数据和二进制 key ,但 C# 代码不断出现 CryptographicException(“填充无效且无法删除”)异常。我的理解是pgcrypto的encrypt()默认是cbc\pkcs。显然,我遗漏了一些东西。

感谢收到的任何帮助。

亚当。

最佳答案

当然,尝试了 Michael 的建议,但没有得到正确的结果。发现了问题。 PG 的 string 到 bytea 转换并不适合粗心的人。重要线索来自

DO $$

declare enc_data bytea;
enc_key bytea;

dec_bytea bytea;
dec_text text;

begin

enc_data := '\305\347fyau\030 \223\014E\307\346\267|\365R\3236l\322f\344\312z\220\271\207C\003\255\210+\316\330&\205l>\342\203\350\214$W\253\370D';
enc_key := '\\xAACE38F289EC3EA209B48D';

dec_bytea := decrypt(enc_data, enc_key, 'aes');
dec_text := dec_bytea::text;

raise info 'Decoded text -> %', dec_text;

DROP TABLE IF EXISTS tmpTable;
CREATE TEMPORARY TABLE tmpTable AS
select dec_text as "Decoded text",
char_length(dec_text) as "Decoded length",
length(enc_data) as "Encoded length",
enc_key as "Enc Key",
length(enc_key) as "Enc Key Len",
encode(enc_key, 'hex') as "Hex key",
encode(enc_key, 'escape') as "Esc key";

END $$;

select * from tmpTable;

这表明 PG 中的二进制 key 长 24 个字节,而不是我预期的 11 个字节。这是我对 PG 的字符串到 bytea 转换工作原理的误解。我以为 "\\xAACE38F289EC3EA209B48D"会转换为 11 字节数组( https://www.postgresql.org/docs/9.6/static/datatype-binary.html ,第 8.4.1 节),但不需要双反斜杠。所以我的字符串转换为 '\'、'x'、'A' ... 'D' - 一个 24 字节数组。

//
// In C# this is the key needed
//
byte[] enc_key_aaaahhhh =
new byte[] { 0x5c, 0x78, 0x41, 0x41, 0x43, 0x45, 0x33, 0x38,
0x46, 0x32, 0x38, 0x39, 0x45, 0x43, 0x33, 0x45,
0x41, 0x32, 0x30, 0x39, 0x42, 0x34, 0x38, 0x44 };

//
// This is wrong.
// For this key you'd need to enter '\xAACE38F289EC3EA209B48D' in PG - only one backslash
//
byte[] enc_key = new byte[] { 0xAA, 0xCE, 0x38, 0xF2, 0x89, 0xEC, 0x3E, 0xA2, 0x09, 0xB4, 0x8D,
0x00, 0x00, 0x00, 0x00, 0x00 };

(我将错误的 GUID 复制到我的 C# 代码中以进行比较并没有帮助 - 真正的 GUID 是“d6edd775-47c5-4779-a761-7f8297130073”。)

希望有一天这对某人有所帮助。

  • 亚当。

关于c# - 解密由 pgcrypto 加密的数据(在 C# 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40492713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com