我的解密密码是1个字符

时间:2017-04-02 17:59:15

标签: c# .net windows cryptography

所以我有这个加密/解密代码:

private string Crypt(string strData, string strPassword, bool bEncrypt)
{        
    byte[] u8_Salt = new byte[] { xxx };

    PasswordDeriveBytes i_Pass = new PasswordDeriveBytes(strPassword, u8_Salt);

    Rijndael i_Alg = Rijndael.Create();
    i_Alg.Key = i_Pass.GetBytes(32);
    i_Alg.IV = i_Pass.GetBytes(16);

    ICryptoTransform i_Trans = (bEncrypt) ? i_Alg.CreateEncryptor() : i_Alg.CreateDecryptor();

    MemoryStream i_Mem = new MemoryStream();
    CryptoStream i_Crypt = new CryptoStream(i_Mem, i_Trans, CryptoStreamMode.Write);

    byte[] u8_Data;
    if (bEncrypt) u8_Data = Encoding.Unicode.GetBytes(strData);
    else u8_Data = Convert.FromBase64String(strData);

    try
    {
        i_Crypt.Write(u8_Data, 0, u8_Data.Length);
        i_Crypt.Close();
    }
    catch { return null; }

    if (bEncrypt) return Convert.ToBase64String(i_Mem.ToArray());
    else return Encoding.Unicode.GetString(i_Mem.ToArray());

}

我试图改进它:

private string Crypt(string strData, string strPassword, bool bEncrypt)
{
    byte[] u8Salt = new byte[] { xxx };

    PasswordDeriveBytes iPass = new PasswordDeriveBytes(strPassword, u8Salt);

    Rijndael iAlg = Rijndael.Create();
    iAlg.Key = iPass.GetBytes(32);
    iAlg.IV = iPass.GetBytes(16);

    ICryptoTransform iTrans = (bEncrypt) ? iAlg.CreateEncryptor() : iAlg.CreateDecryptor();

    MemoryStream iMem = new MemoryStream();
    using (CryptoStream iCrypt = new CryptoStream(iMem, iTrans, CryptoStreamMode.Write))
    {
        byte[] u8Data;
        try
        {
             if (bEncrypt)
                u8Data = Encoding.Unicode.GetBytes(strData);
             else
                u8Data = Convert.FromBase64String(strData);



             iCrypt.Write(u8Data, 0, u8Data.Length);
             if (bEncrypt)
                return Convert.ToBase64String(iMem.ToArray());
             else
                return Encoding.Unicode.GetString(iMem.ToArray());
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

但我发现,返回的解密密码是1个字符太短。我无法看到这个新代码对前者的错误。

1 个答案:

答案 0 :(得分:3)

您的using语句将确保流已关闭,因此会自动刷新。不幸的是,你从MemoryStream 之前的中检索了密文/明文。

不要使用PasswordDeriveBytes,尤其是不要超过20个字节,这是不安全的。而是使用`Rfc2898DeriveBytes