简体   繁体   中英

Aes encrypt .Net and Js

I am new to crypto, and for js crypto also. I am using such .net code for encrypt/decrypt below. And for js I need to encrypt username, and I use this lib http://code.google.com/p/crypto-js/

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

But when I try decrypt value on .net I got 'Padding error' Please help, thanks a lot.

    /// <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);

    }

Question, why are you encrypting passwords within JS? Why don't you ensure your registration / login pages run over a secure connection?

Back to your question, see this question has already been asked in the Google Groups and answered: http://groups.google.com/group/crypto-js/browse_thread/thread/b4f32cc2fc59ec2c#

Edit:

You could also try the default padding scheme for CBC:

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

Seeing that you are assuming default CBC padding in .Net.

PasswordDeriveBytes does not perform PBKDF2, it only performs PBKDF1, and only for the first 20 bytes. Beyond that it is a proprietary, undescribed, badly implemented moronic scheme loosely based on PBKDF1.

You should use Rfc2898DeriveBytes which does implement PBKDF2, like the Google library you are pointing to. Check if the calculated key bytes are correct before proceding further.

Note that the padding exception is the only exception that may be thrown if either the cipher text or key value is incorrect; basically it tells you something is wrong, but not much besides that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM