4

我们有一个小型桌面应用程序,现在需要作为 Web 功能提供(.Net)。这个应用程序包含一些加密代码,并使用 .Net 框架中的 Rijndael 类。该代码接受输入字符串,对其进行加密并将结果写入文件。由于所有代码都包含在一个类中,因此我只是将该类复制到我的 Web 服务应用程序中。当我在原始应用程序和新应用程序中使用相同的密钥加密相同的字符串时,结果是不同的。原始应用程序给出的结果字符串是我的 Web 服务给出的结果字符串的子集。后者在加密字符串的末尾有附加字符。

下面是我正在使用的代码。请注意,我没有开发此代码,也没有完全理解它。关于行为差异的任何想法?请帮忙!!

这是获取用户输入并调用加密器的代码。

    public void EncryptDomain(string EncryptValue, string outputDomainFile)
    {
            if (EncryptValue.Length > 0)
            {
                if ((outputDomainFile != null) && (outputDomainFile.Length > 0))
                {
                    _outputDomainFile = outputDomainFile;
                }

                byte[] input = Encoding.UTF8.GetBytes(EncryptValue);

                Transform(input, TransformType.ENCRYPT);

            }

这是加密器代码:

    private byte[] Transform(byte[] input, TransformType transformType)
    {
        CryptoStream cryptoStream = null;      // Stream used to encrypt
        RijndaelManaged rijndael = null;        // Rijndael provider
        ICryptoTransform rijndaelTransform = null;// Encrypting object            
        FileStream fsIn = null;                 //input file
        FileStream fsOut = null;                //output file
        MemoryStream memStream = null;          // Stream to contain data
        try
        {
            // Create the crypto objects
            rijndael = new RijndaelManaged();
            rijndael.Key = this._Key;
            rijndael.IV = this._IV;
            rijndael.Padding = PaddingMode.Zeros;   

            if (transformType == TransformType.ENCRYPT)
            {
                rijndaelTransform = rijndael.CreateEncryptor();
            }
            else
            {
                rijndaelTransform = rijndael.CreateDecryptor();
            }

            if ((input != null) && (input.Length > 0))
            {
                //memStream = new MemoryStream();
                //string outputDomainFile = 
                FileStream fsOutDomain = new FileStream(_outputDomainFile,
                                            FileMode.OpenOrCreate, FileAccess.Write);

                cryptoStream = new CryptoStream(
                     fsOutDomain, rijndaelTransform, CryptoStreamMode.Write);

                cryptoStream.Write(input, 0, input.Length);

                cryptoStream.FlushFinalBlock();

                //return memStream.ToArray();
                return null;
            }
            return null;

        }
        catch (CryptographicException)
        {
            throw new CryptographicException("Password is invalid. Please verify once again.");
        }
        finally
        {
            if (rijndael != null) rijndael.Clear();
            if (rijndaelTransform != null) rijndaelTransform.Dispose();
            if (cryptoStream != null) cryptoStream.Close();
            if (memStream != null) memStream.Close();
            if (fsOut != null) fsOut.Close();
            if (fsIn != null) fsIn.Close();
        }
 }

设置 IV 值的代码:

    private void GenerateKey(string SecretPhrase)
    {
        // Initialize internal values
        this._Key = new byte[24];
        this._IV = new byte[16];

        // Perform a hash operation using the phrase.  This will 
        // generate a unique 32 character value to be used as the key.
        byte[] bytePhrase = Encoding.ASCII.GetBytes(SecretPhrase);
        SHA384Managed sha384 = new SHA384Managed();
        sha384.ComputeHash(bytePhrase);
        byte[] result = sha384.Hash;

        // Transfer the first 24 characters of the hashed value to the key
        // and the remaining 8 characters to the intialization vector.
        for (int loop = 0; loop < 24; loop++) this._Key[loop] = result[loop];
        for (int loop = 24; loop < 40; loop++) this._IV[loop - 24] = result[loop];
    }
4

2 回答 2

3

我猜这是因为IV(初始化向量)

于 2011-08-04T19:03:40.613 回答
3

这是一个经典的错误。无论您是否自己生成 IV,Rijndael (AES) 都会为您提供一个。诀窍是始终保存 IV(RijndaelManaged 上有一个吸气剂)。

  • 解密时,需要同时传递Key和 IV

如果您将数据保存到文件或数据库中,您可以将 IV 存储为纯文本。您甚至可以将 IV 以纯文本形式通过网络(网络、互联网)传递。攻击者将无法(据我所知)仅根据 IV 破解您的密码。传递或存储 IV 通常是通过在密文前面添加前缀或在末尾附加来完成的。(连接两个字符串)

例如 CiphertextIV 或 IVCiphertext。(记住 IV 是明文,它应该是固定长度的 - 以便在接收解密或数据库插入时轻松分离)

因此,如果您的密钥是 ABCDEFABCDEFABCD并且您的IV 是 ABCDEF0123456789 并且这个明文: “这是一些秘密文本”(比如说)会产生一个密码,例如:abcd1234abcd00

你会像这样传输(或存储)它:ABCDEF0123456789abcd1234abcd00

于 2011-10-31T18:55:52.263 回答