1

Rijndaelこの方法を使用してデータを暗号化および復号化しようとしています。正常に暗号化されますが、復号化しようとすると、メソッドpadding is invalid and cannot be removed の行で表示されます。私は多くのソースを試しましたcs.FlushFinalBlock();private static byte[] DecryptString(byte[] cipherData, byte[] Key, byte[] IV)

これはよくある質問であり、重複している可能性もあります。朝からネットで検索しても解決策がありませんでした。以下は私のコードです。

    //clearText -> the string to be encrypted
    //passowrd -> encryption key
    public string EncryptString(string clearText, string Password)
    {
        // First we need to turn the input string into a byte array. 
        byte[] clearBytes =
            Encoding.Unicode.GetBytes(clearText);

        // Then, we need to turn the password into Key and IV 
        // We are using salt to make it harder to guess our key
        // using a dictionary attack - 
        // trying to guess a password by enumerating all possible words. 
        var pdb = new PasswordDeriveBytes(Password,
                                          new byte[]
                                              {
                                                  0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
                                                  0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
                                              });

        // Now get the key/IV and do the encryption using the
        // function that accepts byte arrays. 
        // Using PasswordDeriveBytes object we are first getting
        // 32 bytes for the Key 
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV. 
        // IV should always be the block size, which is by default
        // 16 bytes (128 bit) for Rijndael. 
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size. 
        // You can also read KeySize/BlockSize properties off
        // the algorithm to find out the sizes. 
        byte[] encryptedData = EncryptString(clearBytes,
                                             pdb.GetBytes(32), pdb.GetBytes(16));

        // Now we need to turn the resulting byte array into a string. 
        // A common mistake would be to use an Encoding class for that.
        //It does not work because not all byte values can be
        // represented by characters. 
        // We are going to be using Base64 encoding that is designed
        //exactly for what we are trying to do. 
        return Convert.ToBase64String(encryptedData);
    }
    //cipherText -> the string to be decrypted
    //passowrd -> decryption key
    public string DecryptString(string cipherText, string Password)
    {
        // First we need to turn the input string into a byte array. 
        // We presume that Base64 encoding was used 
        byte[] cipherBytes = Convert.FromBase64String(cipherText);

        // Then, we need to turn the password into Key and IV 
        // We are using salt to make it harder to guess our key
        // using a dictionary attack - 
        // trying to guess a password by enumerating all possible words. 
        var pdb = new PasswordDeriveBytes(Password,
                                          new byte[]
                                              {
                                                  0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65,
                                                  0x64, 0x76, 0x65, 0x64, 0x65, 0x76
                                              });

        // Now get the key/IV and do the decryption using
        // the function that accepts byte arrays. 
        // Using PasswordDeriveBytes object we are first
        // getting 32 bytes for the Key 
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV. 
        // IV should always be the block size, which is by
        // default 16 bytes (128 bit) for Rijndael. 
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size. 
        // You can also read KeySize/BlockSize properties off
        // the algorithm to find out the sizes. 
        byte[] decryptedData = DecryptString(cipherBytes,
                                             pdb.GetBytes(32), pdb.GetBytes(16));

        // Now we need to turn the resulting byte array into a string. 
        // A common mistake would be to use an Encoding class for that.
        // It does not work 
        // because not all byte values can be represented by characters. 
        // We are going to be using Base64 encoding that is 
        // designed exactly for what we are trying to do. 
        return Encoding.Unicode.GetString(decryptedData);
    }

    // Encrypt a byte array into a byte array using a key and an IV 
    private static byte[] EncryptString(byte[] clearData, byte[] Key, byte[] IV)
    {
        // Create a MemoryStream to accept the encrypted bytes 
        var ms = new MemoryStream();

        // Create a symmetric algorithm. 
        // We are going to use Rijndael because it is strong and
        // available on all platforms. 
        // You can use other algorithms, to do so substitute the
        // next line with something like 
        //      TripleDES alg = TripleDES.Create(); 
        Rijndael alg = Rijndael.Create();

        // Now set the key and the IV. 
        // We need the IV (Initialization Vector) because
        // the algorithm is operating in its default 
        // mode called CBC (Cipher Block Chaining).
        // The IV is XORed with the first block (8 byte) 
        // of the data before it is encrypted, and then each
        // encrypted block is XORed with the 
        // following block of plaintext.
        // This is done to make encryption more secure. 

        // There is also a mode called ECB which does not need an IV,
        // but it is much less secure. 
        alg.Key = Key;
        alg.IV = IV;

        // Create a CryptoStream through which we are going to be
        // pumping our data. 
        // CryptoStreamMode.Write means that we are going to be
        // writing data to the stream and the output will be written
        // in the MemoryStream we have provided. 
        var cs = new CryptoStream(ms,
                                  alg.CreateEncryptor(), CryptoStreamMode.Write);

        // Write the data and make it do the encryption 
        cs.Write(clearData, 0, clearData.Length);

        // Close the crypto stream (or do FlushFinalBlock). 
        // This will tell it that we have done our encryption and
        // there is no more data coming in, 
        // and it is now a good time to apply the padding and
        // finalize the encryption process. 
        cs.FlushFinalBlock();

        // Now get the encrypted data from the MemoryStream.
        // Some people make a mistake of using GetBuffer() here,
        // which is not the right way. 
        byte[] encryptedData = ms.ToArray();

        return encryptedData;
    }

    private static byte[] DecryptString(byte[] cipherData,
                                        byte[] Key, byte[] IV)
    {
        // Create a MemoryStream that is going to accept the
        // decrypted bytes 
        var ms = new MemoryStream();

        // Create a symmetric algorithm. 
        // We are going to use Rijndael because it is strong and
        // available on all platforms. 
        // You can use other algorithms, to do so substitute the next
        // line with something like 
        //     TripleDES alg = TripleDES.Create(); 
        Rijndael alg = Rijndael.Create();

        // Now set the key and the IV. 
        // We need the IV (Initialization Vector) because the algorithm
        // is operating in its default 
        // mode called CBC (Cipher Block Chaining). The IV is XORed with
        // the first block (8 byte) 
        // of the data after it is decrypted, and then each decrypted
        // block is XORed with the previous 
        // cipher block. This is done to make encryption more secure. 
        // There is also a mode called ECB which does not need an IV,
        // but it is much less secure. 
        alg.Key = Key;
        alg.IV = IV;

        // Create a CryptoStream through which we are going to be
        // pumping our data. 
        // CryptoStreamMode.Write means that we are going to be
        // writing data to the stream 
        // and the output will be written in the MemoryStream
        // we have provided. 
        var cs = new CryptoStream(ms,
                                  alg.CreateDecryptor(), CryptoStreamMode.Write);

        // Write the data and make it do the decryption 
        cs.Write(cipherData, 0, cipherData.Length);

        // Close the crypto stream (or do FlushFinalBlock). 
        // This will tell it that we have done our decryption
        // and there is no more data coming in, 
        // and it is now a good time to remove the padding
        // and finalize the decryption process. 
        cs.FlushFinalBlock();

        // Now get the decrypted data from the MemoryStream. 
        // Some people make a mistake of using GetBuffer() here,
        // which is not the right way. 
        byte[] decryptedData = ms.ToArray();

        return decryptedData;
    }

どうもありがとう:) PS :私はオンラインからこのコードをつかみ、私のプログラムに合うように少し編集しました

4

1 に答える 1