AES 解密给出不一致的结果
AES Decryption gives inconsistent results
我曾尝试使用在网上找到的代码来解密给定的字符串,但它给了我一个错误的答案。
在 http://aesencryption.net/ ,如果我只输入字符串、密钥和 128 位,我的字符串在在线工具中被正确解密。但是,在同一页上的 运行 java 代码上,我得到了不同的结果,其中有很多非 utf8 字符。
我不是编码字符串的人,我只知道密钥,字符串是 utf8,我应该使用 AES128,我看到很多在线资源使用其他值,但我没有这些和无论如何,在线工具都有效。
我想让它在 ASP 中运行,但让 java 运行将是不错的第一步。如前所述,我找到的所有在线代码示例都给我乱码,只有这个在线工具对我有用。
字符串是"k8emKaWRSiTa9A0bPSsRoVysvx00EleLD+A8khtH8VVX2tDlI6/DVnLMYUdXWX9MZZKgPJohzpNN6s8bBzzDSzxDXuzx30w7NErpCiaw5zEKQ6Q5pYadG/KMsZ6KwVuRqfEfmKuFP9QWHZS4Bp36lw==",密钥是我得到的16个字符的字符串。
编辑:我试过的示例代码,改编自 http://www.codeproject.com/Articles/5719/Simple-encrypting-and-decrypting-data-in-C(我只将密钥大小从 32 更改为 16 和文本编码):
// Decrypt a string into a string using a password
// Uses Decrypt(byte[], byte[], byte[])
public static string Decrypt(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.
PasswordDeriveBytes 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 = Decrypt(cipherBytes,
pdb.GetBytes(16), 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 System.Text.Encoding.UTF8.GetString(decryptedData);
}
// Decrypt a byte array into a byte array using a key and an IV
public static byte[] Decrypt(byte[] cipherData,
byte[] Key, byte[] IV)
{
// Create a MemoryStream that is going to accept the
// decrypted bytes
MemoryStream 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.
CryptoStream 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.Close();
// 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;
}
我使用
让它工作
public string AES_DEC(string text, string password)
{
RijndaelManaged aes256 = new RijndaelManaged();
aes256.KeySize = 128;
aes256.BlockSize = 128;
aes256.Padding = PaddingMode.PKCS7;
aes256.Mode = CipherMode.ECB;
aes256.Key = Encoding.UTF8.GetBytes(password);
aes256.GenerateIV();
byte[] encryptedData = Convert.FromBase64String(text);
ICryptoTransform transform = aes256.CreateDecryptor();
byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return Encoding.UTF8.GetString(plainText);
}
我仍然不知道我做错了什么
我曾尝试使用在网上找到的代码来解密给定的字符串,但它给了我一个错误的答案。
在 http://aesencryption.net/ ,如果我只输入字符串、密钥和 128 位,我的字符串在在线工具中被正确解密。但是,在同一页上的 运行 java 代码上,我得到了不同的结果,其中有很多非 utf8 字符。
我不是编码字符串的人,我只知道密钥,字符串是 utf8,我应该使用 AES128,我看到很多在线资源使用其他值,但我没有这些和无论如何,在线工具都有效。
我想让它在 ASP 中运行,但让 java 运行将是不错的第一步。如前所述,我找到的所有在线代码示例都给我乱码,只有这个在线工具对我有用。
字符串是"k8emKaWRSiTa9A0bPSsRoVysvx00EleLD+A8khtH8VVX2tDlI6/DVnLMYUdXWX9MZZKgPJohzpNN6s8bBzzDSzxDXuzx30w7NErpCiaw5zEKQ6Q5pYadG/KMsZ6KwVuRqfEfmKuFP9QWHZS4Bp36lw==",密钥是我得到的16个字符的字符串。
编辑:我试过的示例代码,改编自 http://www.codeproject.com/Articles/5719/Simple-encrypting-and-decrypting-data-in-C(我只将密钥大小从 32 更改为 16 和文本编码):
// Decrypt a string into a string using a password
// Uses Decrypt(byte[], byte[], byte[])
public static string Decrypt(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.
PasswordDeriveBytes 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 = Decrypt(cipherBytes,
pdb.GetBytes(16), 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 System.Text.Encoding.UTF8.GetString(decryptedData);
}
// Decrypt a byte array into a byte array using a key and an IV
public static byte[] Decrypt(byte[] cipherData,
byte[] Key, byte[] IV)
{
// Create a MemoryStream that is going to accept the
// decrypted bytes
MemoryStream 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.
CryptoStream 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.Close();
// 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;
}
我使用
让它工作 public string AES_DEC(string text, string password)
{
RijndaelManaged aes256 = new RijndaelManaged();
aes256.KeySize = 128;
aes256.BlockSize = 128;
aes256.Padding = PaddingMode.PKCS7;
aes256.Mode = CipherMode.ECB;
aes256.Key = Encoding.UTF8.GetBytes(password);
aes256.GenerateIV();
byte[] encryptedData = Convert.FromBase64String(text);
ICryptoTransform transform = aes256.CreateDecryptor();
byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return Encoding.UTF8.GetString(plainText);
}
我仍然不知道我做错了什么