2 回答
TA贡献1829条经验 获得超9个赞
这是你的代码
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
class AES_CFB_XorKeyStream
{
static void Main(string[] args)
{
byte[] data = Encoding.UTF8.GetBytes("0123456789");
byte [] k1 = Encoding.UTF8.GetBytes("0123456789abcdef");
byte [] r1 = Encoding.UTF8.GetBytes("1234567890abcdef");
Console.WriteLine("original " + BitConverter.ToString(data));
using (RijndaelManaged Aes128 = new RijndaelManaged())
{
Aes128.BlockSize = 128;
Aes128.KeySize = 128;
Aes128.Mode = CipherMode.CFB;
Aes128.FeedbackSize = 128;
Aes128.Padding = PaddingMode.None;
Aes128.Key = k1;
Aes128.IV = r1;
using (var encryptor = Aes128.CreateEncryptor())
using (var msEncrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))
{
bw.Write(data);
bw.Close();
data = msEncrypt.ToArray();
Console.WriteLine("crypted " + BitConverter.ToString(data));
}
}
using (RijndaelManaged Aes128 = new RijndaelManaged())
{
Aes128.BlockSize = 128;
Aes128.KeySize = 128;
Aes128.Mode = CipherMode.CFB;
Aes128.FeedbackSize = 128;
Aes128.Padding = PaddingMode.None;
Aes128.Key = k1;
Aes128.IV = r1;
using (var decryptor = Aes128.CreateDecryptor())
using (var msEncrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Write))
using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))
{
bw.Write(data);
bw.Close();
data = msEncrypt.ToArray();
Console.WriteLine("decrypted " + BitConverter.ToString(data));
}
}
}
}
输出
original 30-31-32-33-34-35-36-37-38-39
crypted 76-2B-6D-CE-A9-C2-A7-46-0D-B7
decrypted 30-31-32-33-34-35-36-37-38-39
TA贡献1784条经验 获得超9个赞
我遇到了完全相同的问题,只有每个解密块的第一个字节是正确的,但我没有能够在 Go 程序上更改源代码的奢侈。
我最终实现了自己的填充。只需用 0 字节填充加密字节,使其可被 128 的块大小整除,然后在运行解密例程后,从末尾切掉该字节数。
示例代码:
using System;
using System.Text;
using System.Security.Cryptography;
using System.Linq;
public static class Program
{
static RijndaelManaged aes = new RijndaelManaged(){
Mode = CipherMode.CFB,
BlockSize = 128,
KeySize = 128,
FeedbackSize = 128,
Padding = PaddingMode.None
};
public static void Main(){
byte[] key = Encoding.UTF8.GetBytes("0123456789abcdef");
byte[] iv = Encoding.UTF8.GetBytes("1234567890abcdef");
byte[] encryptedBytes = new byte[]{0x76, 0x2b, 0x6d, 0xce, 0xa9, 0xc2, 0xa7, 0x46, 0x0d, 0xb7};
// Custom pad the bytes
int padded;
encryptedBytes = PadBytes(encryptedBytes, aes.BlockSize, out padded);
// Decrypt bytes
byte[] decryptedBytes = DecryptBytesAES(encryptedBytes, key, iv, encryptedBytes.Length);
// Check for successful decrypt
if(decryptedBytes != null){
// Unpad
decryptedBytes = UnpadBytes(decryptedBytes, padded);
Console.Write("Decrypted: " + Encoding.UTF8.GetString(decryptedBytes));
}
}
// Just an elegant way of initializing an array with bytes
public static byte[] Initialize(this byte[] array, byte value, int length)
{
for (int i = 0; i < array.Length; i++)
{
array[i] = value;
}
return array;
}
// Custom padding to get around the issue of how Go uses CFB mode without padding differently than C#
public static byte[] PadBytes(byte[] encryptedBytes, int blockSize, out int numPadded)
{
numPadded = 0;
// Check modulus of block size
int mod = encryptedBytes.Length % blockSize;
if (mod != 0)
{
// Calculate number to pad
numPadded = blockSize - mod;
// Build array
return encryptedBytes.Concat(new byte[numPadded].Initialize(0, numPadded)).ToArray();
}
else {
// No padding needed
return encryptedBytes;
}
}
public static byte[] UnpadBytes(byte[] decryptedBytes, int numPadded)
{
if(numPadded != 0)
{
byte[] unpaddedBytes = new byte[decryptedBytes.Length - numPadded];
Array.Copy(decryptedBytes, unpaddedBytes, unpaddedBytes.Length);
return unpaddedBytes;
}
else
{
return decryptedBytes;
}
}
public static byte[] DecryptBytesAES(byte[] cipherText, byte[] Key, byte[] IV, int size)
{
byte[] array = new byte[size];
try{
aes.Key = Key;
aes.IV = IV;
ICryptoTransform transform = aes.CreateDecryptor(aes.Key, aes.IV);
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(cipherText))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read))
{
cryptoStream.Read(array, 0, size);
}
}
}
catch(Exception e){
return null;
}
return array;
}
}
.NET 小提琴:https : //dotnetfiddle.net/NPHKN3
- 2 回答
- 0 关注
- 157 浏览
添加回答
举报