【问题标题】:Encryption output always different even with same key即使使用相同的密钥,加密输出也总是不同
【发布时间】:2010-09-12 05:27:43
【问题描述】:

我正在尝试将密码存储在我想稍后检索的文件中。哈希不是一个选项,因为我需要密码才能稍后连接到远程服务器。

以下代码运行良好,但即使密钥相同,每次都会创建不同的输出。这很糟糕,因为当应用程序关闭并重新启动时,我将无法再检索我的密码。如何将密码存储在文件中并在以后检索它们?

public class EncyptDecrypt {

    static System.Security.Cryptography.TripleDESCryptoServiceProvider keyProv = new System.Security.Cryptography.TripleDESCryptoServiceProvider();

    public static System.Security.Cryptography.TripleDESCryptoServiceProvider KeyProvider {
        get {
            keyProv.Key = new byte[] { /* redacted with prejudice */ };
            return keyProv;
        }
    }

    public static string Encrypt(string text, SymmetricAlgorithm key) {

        if (text.Equals(string.Empty)) return text;

        // Create a memory stream.
        MemoryStream ms = new MemoryStream();

        // Create a CryptoStream using the memory stream and the
        // CSP DES key.
        CryptoStream encStream = new CryptoStream(ms, key.CreateEncryptor(), CryptoStreamMode.Write);

        // Create a StreamWriter to write a string
        // to the stream.
        StreamWriter sw = new StreamWriter(encStream);

        // Write the plaintext to the stream.
        sw.WriteLine(text);

        // Close the StreamWriter and CryptoStream.
        sw.Close();
        encStream.Close();

        // Get an array of bytes that represents
        // the memory stream.
        byte[] buffer = ms.ToArray();

        // Close the memory stream.
        ms.Close();

        // Return the encrypted byte array.
        return System.Convert.ToBase64String(buffer);
    }

    // Decrypt the byte array.
    public static string Decrypt(string cypherText, SymmetricAlgorithm key) {

        if (cypherText.Equals(string.Empty)) return cypherText;

        string val;

        try {
            // Create a memory stream to the passed buffer.
            MemoryStream ms = new MemoryStream(System.Convert.FromBase64String(cypherText));

            // Create a CryptoStream using the memory stream and the
            // CSP DES key.
            CryptoStream encStream = new CryptoStream(ms, key.CreateDecryptor(), CryptoStreamMode.Read);

            // Create a StreamReader for reading the stream.
            StreamReader sr = new StreamReader(encStream);

            // Read the stream as a string.
            val = sr.ReadLine();

            // Close the streams.
            sr.Close();
            encStream.Close();
            ms.Close();
        }
        catch (System.Exception) {

            return string.Empty;
        }

        return val;
    }
}

【问题讨论】:

    标签: c# encryption cryptography


    【解决方案1】:

    我相信正在发生的事情是加密提供者正在随机生成一个 IV。指定它,它应该不再不同。

    编辑:您可以通过设置 IV 属性在“keyProvider”中执行此操作。

    【讨论】:

    • 请注意,IV 是与密钥一起提供的附加数据。此信息是公开的,不必隐藏,如果隐藏,也不会增加安全性。它用于使密码分析更加困难。
    • 实现也可以用随机数据填充吗?我不知道是不是这样,只是说在某些分组密码模式下是合适的。
    • 它会在加密之前用零填充,IIRC。即便如此,您也只会在最后一个 字节中看到不同的数据。当然,提问者没有具体说明/how/不同的数据,所以谁知道呢。
    • 我只是在思考“如果这个想法不能解决它,那么下一步是什么”。既然你被录取了,我猜这只是静脉注射。
    • 手动指定 IV 也(通常)是个坏主意。用相同的 IV 加密多个明文是一个真的坏主意。为什么相同明文的输出始终相同很重要?
    【解决方案2】:

    根据 CreateEncryptor 的文档:

    如果当前 IV 属性为空 参考(Visual Basic 中没有), 调用 GenerateIV 方法 创建一个新的随机 IV。

    这会使密文每次都不一样。

    注意:here 讨论了解决此问题的方法,我建议您可以在明文前面加上 mac ...然后密文的第一个块实际上是 IV,但它都是可重复的

    【讨论】:

      【解决方案3】:

      您需要指定一个 IV(初始化向量),即使您生成一个随机向量。如果您使用随机 IV,那么您必须将其与密文一起存储,以便稍后在解密时使用它,或者您可以从其他一些数据中导出 IV(例如,如果您正在加密密码,您可以从用户名)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-02
        • 2012-09-10
        • 1970-01-01
        • 1970-01-01
        • 2011-10-29
        • 2016-10-15
        • 2017-06-02
        • 1970-01-01
        相关资源
        最近更新 更多