如何复制此在线工具使用的AES加密

时间:2014-06-06 11:21:38

标签: c# encryption aes

http://aes.online-domain-tools.com/

我正在尝试使用CBC使用CBC复制此加密,但无论我尝试什么,都无法获得相同的结果。

到目前为止我的代码:

    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();
    }
}

1 个答案:

答案 0 :(得分:3)

好的,所以根据描述,密钥用零字节填充。您实际上正在重复关键字节。这两种方法当然都是完全不安全的,密钥应该只包含随机字节。

IV似乎是在使用SHA-1填充之前计算的关键字节数。我的代码中没有看到任何相关内容。请注意,每次使用相同的密钥时,IV都应该更改,因此在密钥上使用SHA-1是不安全的。

填充为零填充,最大为块的大小。这意味着如果您的明文以00字节结尾,则会丢失数据。没有提到填充,但是我通过加密某些内容然后使用相同的密钥对其进行解密来测试它。似乎填充字节仍然存在。这不是不安全的,但由于它可能导致无效的明文,这绝对是错误的。

没有添加身份验证标记(例如HMAC),这意味着任何人都可以更改密文并远离它。在最好的情况下,这将导致其他系统上的垃圾。在最糟糕的情况下(这很可能是这个)你也会完全失去机密性。这可能就是你首先想要实现的目标。

我希望我已经给你足够的指针来创建一个实现 - 用于学习目的或从给定的代码迁移。如果你使用随机垃圾 - 没有其他的话 - 来自互联网,你将最终没有安全性。我不会提供代码,因为我不想让它扩散。