【问题标题】:Aes encrypt .Net and JsAes 加密 .Net 和 Js
【发布时间】:2012-03-13 08:52:38
【问题描述】:

我是加密新手,对于 js 加密也是如此。我正在使用这样的.net 下面的加密/解密代码。 而对于js我需要加密用户名,我使用这个库http://code.google.com/p/crypto-js/

Crypto.AES.encrypt("q", "test", { mode: new Crypto.mode.CBC(Crypto.pad.pkcs7) })

但是当我尝试在 .net 上解密值时,我得到了“填充错误” 请帮忙,非常感谢。

    /// <summary>
    /// Method which does the encryption using Rijndeal algorithm
    /// </summary>
    /// <param name="InputText">Data to be encrypted</param>
    /// <param name="Password">The string to used for making the key.The same string
    /// should be used for making the decrpt key</param>
    /// <returns>Encrypted Data</returns>
    public static string EncryptString(string InputText, string Password)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();


        byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());

        //This class uses an extension of the PBKDF1 algorithm defined in the PKCS#5 v2.0 
        //standard to derive bytes suitable for use as key material from a password. 
        //The standard is documented in IETF RRC 2898.

        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
        //Creates a symmetric encryptor object. 
        ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
        MemoryStream memoryStream = new MemoryStream();
        //Defines a stream that links data streams to cryptographic transformations
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(PlainText, 0, PlainText.Length);
        //Writes the final state and clears the buffer
        cryptoStream.FlushFinalBlock();
        byte[] CipherBytes = memoryStream.ToArray();
        memoryStream.Close();
        memoryStream = null;
        cryptoStream.Close();
        cryptoStream = null;
        PlainText = null;
        Salt = null;
        try
        {
            GC.Collect();
        }
        catch { }
        return Convert.ToBase64String(CipherBytes);

    }

    /// <summary>
    /// Method which does the encryption using Rijndeal algorithm.This is for decrypting the data
    /// which has orginally being encrypted using the above method
    /// </summary>
    /// <param name="InputText">The encrypted data which has to be decrypted</param>
    /// <param name="Password">The string which has been used for encrypting.The same string
    /// should be used for making the decrypt key</param>
    /// <returns>Decrypted Data</returns>
    public static string DecryptString(string InputText, string Password)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();


        byte[] EncryptedData = Convert.FromBase64String(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
        //Making of the key for decryption
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
        //Creates a symmetric Rijndael decryptor object.
        ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
        MemoryStream memoryStream = new MemoryStream(EncryptedData);
        //Defines the cryptographics stream for decryption.THe stream contains decrpted data
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
        byte[] PlainText = new byte[EncryptedData.Length];
        int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);
        memoryStream.Close();
        memoryStream = null;
        cryptoStream.Close();
        cryptoStream = null;
        Salt = null;
        try
        {
            GC.Collect();
        }
        catch { }
        //Converting to string
        return Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);

    }

【问题讨论】:

  • 你过得怎么样,你可以使用 Rfc2898DeriveBytes 复制关键字节,如答案中所示?不要忘记跟进您的问题。

标签: javascript .net aes encryption


【解决方案1】:

问题,你为什么要在 JS 中加密密码?为什么不确保您的注册/登录页面通过安全连接运行?

回到你的问题,看到这个问题已经在 Google Groups 中提出并回答了:http://groups.google.com/group/crypto-js/browse_thread/thread/b4f32cc2fc59ec2c#

编辑:

您也可以尝试 CBC 的默认填充方案:

var crypted = Crypto.AES.encrypt("Message", "Secret Passphrase", { mode: new Crypto.mode.CBC });

看到您在 .Net 中假设默认 CBC 填充。

【讨论】:

  • 感谢您的回复。我有转换字符串,但它仍然触发“填充无效,无法删除。”在 .net 中解密代码 :( 我的代码示例 Crypto.AES.encrypt(stringToUnicodeBytes("q"), stringToUnicodeBytes("Yosef!"), { mode: new Crypto.mode.CBC(Crypto.pad.pkcs7) }) 来自这一行我得到“fCbxmcwBl5yfgoRm1LgoSRZlUlwTxmVbI9oS/mMrIuE =”但是.net代码给了我的“hJelPY4RCl7H
【解决方案2】:

PasswordDeriveBytes 不执行 PBKDF2,它只执行 PBKDF1,并且只针对前 20 个字节。除此之外,它是一种基于 PBKDF1 的专有的、未描述的、实施不佳的 moronic 方案。

您应该使用实现 PBKDF2 的 Rfc2898DeriveBytes,就像您指向的 Google 库一样。在进一步处理之前检查计算的密钥字节是否正确。

请注意,如果密文或密钥值不正确,则填充异常是唯一可能引发的异常;基本上它会告诉你有些事情是错误的,但除此之外没有太多。

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2020-12-03
    • 2014-02-06
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多