Rijndael
この方法を使用してデータを暗号化および復号化しようとしています。正常に暗号化されますが、復号化しようとすると、メソッドpadding is invalid and cannot be removed
の行で表示されます。私は多くのソースを試しましたcs.FlushFinalBlock();
private static byte[] DecryptString(byte[] cipherData, byte[] Key, byte[] IV)
- RijndaelManaged "パディングが無効であり、削除できません" は、本番環境で復号化するときにのみ発生します
- EOF が例外をスローする前に復号化を停止しています: パディングが無効であり、削除できません
- http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/0fa69204-3bba-48a9-9bdc-32a12b0da4a0
これはよくある質問であり、重複している可能性もあります。朝からネットで検索しても解決策がありませんでした。以下は私のコードです。
//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 :私はオンラインからこのコードをつかみ、私のプログラムに合うように少し編集しました