Masalah dengan mendekripsi AES/ECB yang diisi menggunakan PCKS5 di C#


Saya perlu mendekripsi gambar yang berasal dari layanan online (yang bukan milik saya, jadi saya harus menggunakan cara enkripsi ini).
Gambar ini dienkripsi menggunakan AES/ECB dengan satu kunci sinkron dan diisi menggunakan PKCS5.

Saya mencoba beberapa cara untuk mencapai hal ini, tetapi tidak ada yang berhasil. Saya menggunakan perpustakaan kriptografi BoucyCastle.

Ini kode dekripsi saya:

    public static byte[] Decrypt(string input)
    {
        var cipher = CipherUtilities.GetCipher("AES/ECB/PKCS5Padding");
        cipher.Init(false, new KeyParameter(Encoding.UTF8.GetBytes(KEY)));
        byte[] todo = Encoding.UTF8.GetBytes(Pad(input));
        byte[] bytes = cipher.ProcessBytes(todo);
        byte[] final = cipher.DoFinal();

        // Write the decrypt bytes & final to memory...
        var decryptedStream = new MemoryStream(bytes.Length);
        decryptedStream.Write(bytes, 0, bytes.Length);
        decryptedStream.Write(final, 0, final.Length);
        decryptedStream.Flush();

        var decryptedData = new byte[decryptedStream.Length];
        decryptedStream.Read(decryptedData, 0, (int)decryptedStream.Length);
        return decryptedData;
    }

    private static string Pad(string data)
    {
        int len = data.Length;
        int toAdd = (16 - len % 16);
        for (int i = 0; i < toAdd; i++)
        {
            data += (char)toAdd;
        }
        return data;
    }

Ketika saya mencobanya, muncul InvalidCipherTextExpression dengan pesan "pad block rusak", di baris byte[] final = cipher.DoFinal();.
Saya menguji fungsi padding saya dan sepertinya berfungsi seperti yang diharapkan.
Saya mencoba mencari ke dalam kode sumber BouncyCastle untuk mencari kesalahan saya, dan yang saya temukan adalah blok terakhir tidak memiliki padding apa pun, dan itulah yang menyebabkan kesalahan tersebut. Jadi saya bertanya-tanya apakah saya melakukan sesuatu yang salah di tempat lain, karena itu mungkin bukan berasal dari padding.
Mungkin string input, yang diambil dari server http dengan ini :

        // grab te response and print it out to the console along with the status code
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        return new StreamReader(response.GetResponseStream()).ReadToEnd();

Apa yang ingin saya capai adalah hal yang persis sama seperti di sini: C# Mendekripsi AES /ECB Paddded Menggunakan PKCS#5
Tapi tidak ada tenda karena penanya tidak mencoba apa pun..

Terima kasih sebelumnya, dan saya benar-benar minta maaf atas bahasa Inggris saya yang buruk.


person Rom11    schedule 13.01.2014    source sumber
comment
dengan satu kunci sinkron Apa itu kunci sinkron?   -  person Duncan Jones    schedule 13.01.2014
comment
Saya tidak begitu tahu, itulah yang saya temukan di dokumentasi.   -  person Rom11    schedule 13.01.2014
comment
OKE. Karena tertarik, apakah Anda dapat menautkan ke dokumentasinya?   -  person Duncan Jones    schedule 13.01.2014
comment
gibsonsec.org/snapchat/fulldisclosure/#encrypting-normal-snaps Saya menemukan ini di sini. (Saya tidak tahu apakah saya berwenang untuk memposting ini di sini, karena ini bukan dokumentasi resmi..)   -  person Rom11    schedule 13.01.2014
comment
Mengapa Anda melakukan padding sebelum dekripsi? Urutan operasinya adalah pad -› encrypt -› transmit -› decrypt -› unpad.   -  person wallenborn    schedule 13.01.2014
comment
@wallenborn Benar. Faktanya, Anda tidak perlu khawatir tentang unpadding sama sekali - lib BouncyCastle akan melakukannya untuk Anda.   -  person Duncan Jones    schedule 13.01.2014
comment
Saya melakukan padding sebelum mendekripsi seperti yang saya lihat di implementasi lain dengan Python dan itu berfungsi dengan baik. Ketika saya mencoba mendekripsi tanpa padding, saya mendapatkan kesalahan lain: blok terakhir tidak lengkap dalam dekripsi   -  person Rom11    schedule 13.01.2014


Jawaban (1)


Anda memiliki ciphertext yang tidak lengkap - data yang dienkripsi dengan AES-128 akan selalu berupa kelipatan 128/8 = 16 byte. Yaitu. Last block incomplete in decryption berarti Anda memiliki, katakanlah, 127 byte teks tersandi, bukan 128.

Seperti yang dikatakan dalam komentar, Anda tidak boleh memasukkan ciphertext sebelum dekripsi. "Berhasil" karena fungsi Anda sebenarnya tidak menghasilkan apa pun - karena alasan yang disorot di atas.

Apakah Anda yakin Anda menggunakan rasa "bitness" yang sama dari AES? (misalnya, Anda mungkin mendekripsi ciphertext AES-128 dengan AES-192)

P.S. Pada catatan yang tidak berhubungan, cipher.Init(false, new KeyParameter(Encoding.UTF8.GetBytes(KEY))); juga terlihat mencurigakan. Apakah Anda yakin itu bukan Base64 atau sejenisnya?

person DarkWanderer    schedule 13.01.2014
comment
Persis seperti ini, terima kasih! Masalahnya datang dari kenyataan saya mendapatkan byte dari string, dan kehilangan sebagian. Sekarang saya mendapatkan byte langsung dari aliran respons HTTP! - person Rom11; 13.01.2014