http://aes.online-domain-tools.com/
我正在尝试使用 CBC 通过 C# 复制此加密,但无论我如何尝试都没有得到相同的结果。
到目前为止我的代码:
private byte[] hex2bytes(string s)
{
return Enumerable.Range(0, s.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(s.Substring(x, 2), 16))
.ToArray();
}
private AesCryptoServiceProvider GetProvider(byte[] key)
{
AesCryptoServiceProvider result = new AesCryptoServiceProvider();
result.BlockSize = 128;
result.KeySize = 128;
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7;
result.GenerateIV();
//result.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
result.IV = hex2bytes("ad77d666311839f5665aeb2e42f64542");
byte[] RealKey = GetKey(key, result);
_key = Encoding.ASCII.GetString(RealKey);
result.Key = RealKey;
// result.IV = RealKey;
return result;
}
private byte[] GetKey(byte[] suggestedKey, SymmetricAlgorithm p)
{
byte[] kRaw = suggestedKey;
List<byte> kList = new List<byte>();
for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8)
{
kList.Add(kRaw[(i / 8) % kRaw.Length]);
}
byte[] k = kList.ToArray();
return k;
}
/// <summary>
/// Encrpyts the sourceString, returns this result as an Aes encrpyted, BASE64 encoded string
/// </summary>
/// <param name="plainSourceStringToEncrypt">a plain, Framework string (ASCII, null terminated)</param>
/// <param name="passPhrase">The pass phrase.</param>
/// <returns>
/// returns an Aes encrypted, BASE64 encoded string
/// </returns>
public string EncryptString(string plainSourceStringToEncrypt, string passPhrase)
{
//Set up the encryption objects
using (AesCryptoServiceProvider acsp = GetProvider(Encoding.UTF8.GetBytes(passPhrase)))
{
byte[] sourceBytes = Encoding.UTF8.GetBytes(plainSourceStringToEncrypt);
ICryptoTransform ictE = acsp.CreateEncryptor();
//Set up stream to contain the encryption
MemoryStream msS = new MemoryStream();
//Perform the encrpytion, storing output into the stream
CryptoStream csS = new CryptoStream(msS, ictE, CryptoStreamMode.Write);
csS.Write(sourceBytes, 0, sourceBytes.Length);
csS.FlushFinalBlock();
//sourceBytes are now encrypted as an array of secure bytes
byte[] encryptedBytes = msS.ToArray(); //.ToArray() is important, don't mess with the buffer
var x = BitConverter.ToString(encryptedBytes);
//return the encrypted bytes as a BASE64 encoded string
return Convert.ToBase64String(encryptedBytes);
}
}
/// <summary>
/// Decrypts a BASE64 encoded string of encrypted data, returns a plain string
/// </summary>
/// <param name="base64StringToDecrypt">an Aes encrypted AND base64 encoded string</param>
/// <param name="passphrase">The passphrase.</param>
/// <returns>returns a plain string</returns>
public string DecryptString(string base64StringToDecrypt, string passphrase)
{
//Set up the encryption objects
using (AesCryptoServiceProvider acsp = GetProvider(Encoding.UTF8.GetBytes(passphrase)))
{
byte[] RawBytes = Convert.FromBase64String(base64StringToDecrypt);
ICryptoTransform ictD = acsp.CreateDecryptor();
//RawBytes now contains original byte array, still in Encrypted state
//Decrypt into stream
MemoryStream msD = new MemoryStream(RawBytes, 0, RawBytes.Length);
CryptoStream csD = new CryptoStream(msD, ictD, CryptoStreamMode.Read);
//csD now contains original byte array, fully decrypted
//return the content of msD as a regular string
return (new StreamReader(csD)).ReadToEnd();
}
}
最佳答案
好的,所以根据描述, key 是用零字节填充的。您实际上是在重复关键字节。这两种方法当然都是完全不安全的, key 应该只包含随机字节。
IV 似乎是在填充 key 字节之前使用 SHA-1 计算的。我在你的代码中没有看到任何相关内容。请注意,每次使用相同的 key 时,IV 都应该更改,因此在 key 上使用 SHA-1 是不安全的。
填充是零填充,最多可达 block 的大小。这意味着如果您的明文以 00 字节结尾,您将丢失数据。没有提到填充,但我通过加密某些内容然后使用相同的 key 对其进行解密来测试了这一点。看来填充字节仍然存在。这并不是不安全,但由于它可能会导致无效的明文,因此肯定是错误的。
没有添加身份验证标签(例如 HMAC),这意味着任何人都可以更改密文并逃脱惩罚。在最好的情况下,这只会导致其他系统上出现垃圾。在最坏的情况下(这是最有可能的),您也将完全失去保密性。这可能就是您首先想要实现的目标。
我希望我已经为您提供了足够的指导来创建实现 - 出于学习目的或从给定的代码迁移。如果您使用来自互联网的随机垃圾(没有别的词可以形容这一点),那么您最终的安全性将为零。我不会提供代码,因为我不希望这种情况激增。
关于c# - 如何复制此在线工具使用的 AES 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080630/