2016-11-08 57 views
3

私はpgcryptoを使用して暗号化されたデータを復号しようとしています。唯一のテストなのでIVを使用しませんでしたが、C#でデータを復号化できません。pgcryptoで暗号化されたデータの復号化(C#で)

POSTGRESで暗号化:

C位における復号
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)); 

// 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 

Iは、行の1つ、およびバイナリキーに起因する暗号化されたデータをコピーするが、C#コードを用いて発泡続けますCryptographicException( "パディングは無効で、削除できません")例外。私の理解は、pgcryptoのencrypt()のデフォルトはcbc \ pkcsです。明らかに、私は何かを欠いている。

喜んでお寄せいただきありがとうございます。

アダム。

+0

おそらく、C#関数でデータを暗号化し、暗号化されたデータをPostGresデータと100%一致させることができます。それらが一致すると、2つのシステム間で切断がどこにあるかを見つけることができます。 –

+0

ありがとう、マイケル - 良い提案。私はそれを試してみます。または、私がC#で暗号化と復号化を開始できることを確認することさえできます。 –

答えて

3

マイケルの提案を試してみて、正しい結果を得られなかったのはもちろんです。問題が見つかりました。 PGの文字列からバイトへの変換は不注意ではありません。私は期待通りではない11 - 重要な手掛かりが

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でバイナリキーが長い24バイトであることを示しました。 PGの文字列からバイトへの変換がどのように機能するかについては、誤解されていました。 "\\ 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 }; 

(私はと比較するために、私のC#のコードに間違ったGUIDをコピーしたことを助けていない - 。本当のGUIDは、 "d6edd775-47c5-4779-a761-7f8297130073" だった)

・ホープ、この多分ある日誰かを助ける。

  • アダム。
+0

nice、ありがとう – lhk

+0

うれしいよ:) –