Equivalent of Rfc2898DeriveBytes in javascript?

2.6k views Asked by At

I've seen C# code that can encrypt, and later decrypt, a password using code like this:

http://wp7-travel.googlecode.com/svn/trunk/SilverlightPhoneDatabase/Cryptography.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Reflection;

namespace SilverlightPhoneDatabase
{
    /// <summary>
    /// Class used to encrypt the database
    /// </summary>
    public static class Cryptography
    {

        /// <summary>
        /// Incrypt the input using password provided
        /// </summary>
        /// <param name="input">Input string to encrypt</param>
        /// <param name="password">Password to use</param>
        /// <returns>Encrypted string</returns>
        public static string Encrypt(string input, string password)
        {

            string data = input;
            byte[] utfdata = UTF8Encoding.UTF8.GetBytes(data);
            byte[] saltBytes = UTF8Encoding.UTF8.GetBytes(password);



            // Our symmetric encryption algorithm
            AesManaged aes = new AesManaged();

            // We're using the PBKDF2 standard for password-based key generation
            Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);

            // Setting our parameters
            aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
            aes.KeySize = aes.LegalKeySizes[0].MaxSize;
            aes.Key = rfc.GetBytes(aes.KeySize / 8);
            aes.IV = rfc.GetBytes(aes.BlockSize / 8);

            // Encryption
            ICryptoTransform encryptTransf = aes.CreateEncryptor();

            // Output stream, can be also a FileStream
            MemoryStream encryptStream = new MemoryStream();
            CryptoStream encryptor = new CryptoStream(encryptStream, encryptTransf, CryptoStreamMode.Write);

            encryptor.Write(utfdata, 0, utfdata.Length);
            encryptor.Flush();
            encryptor.Close();

            byte[] encryptBytes = encryptStream.ToArray();
            string encryptedString = Convert.ToBase64String(encryptBytes);

            return encryptedString;
        }

        /// <summary>
        /// Decrypt string using password provided
        /// </summary>
        /// <param name="base64Input">Input to decrypt</param>
        /// <param name="password">Password to use</param>
        /// <returns>Decrypted string</returns>
        public static string Decrypt(string base64Input, string password)
        {

            byte[] encryptBytes = Convert.FromBase64String(base64Input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);

            // Our symmetric encryption algorithm
            AesManaged aes = new AesManaged();

            // We're using the PBKDF2 standard for password-based key generation
            Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);

            // Setting our parameters
            aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
            aes.KeySize = aes.LegalKeySizes[0].MaxSize;
            aes.Key = rfc.GetBytes(aes.KeySize / 8);
            aes.IV = rfc.GetBytes(aes.BlockSize / 8);

            // Now, decryption
            ICryptoTransform decryptTrans = aes.CreateDecryptor();

            // Output stream, can be also a FileStream
            MemoryStream decryptStream = new MemoryStream();
            CryptoStream decryptor = new CryptoStream(decryptStream, decryptTrans, CryptoStreamMode.Write);

            decryptor.Write(encryptBytes, 0, encryptBytes.Length);
            decryptor.Flush();
            decryptor.Close();

            byte[] decryptBytes = decryptStream.ToArray();
            string decryptedString = UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
            return decryptedString;
        }
    }
}

I am no security expert and have limited experience with crypto algorithms. I have an encrypted password that was encrypted by that kind of code, and now want to access the decrypted password in a node.js program (Javascript).

It seems that crypto-js has a pbkdf2.js module but it only knows how to encrypt a password.

I have seen http://anandam.name/pbkdf2/ but again it seems to be an encrypter only. No decryption.

Can anyone provide code that would decrypt a password, given a known salt and iterations that were used to encrypt it, using plain Javascript, preferably leveraging common modules like crypto-js?

1

There are 1 answers

0
Maarten Bodewes On BEST ANSWER

PBKDF is password based key derivation function. PBKDF's are not encryption algorithms. They can be compared to one way secure hash algorithms with a salt (to make the output for identical passwords unique) and iteration count (to make them slow). Many PBKDF's, such as PBKDF2 in your question, are actually implemented using hash algorithms like SHA-1.

PBKDF functions are often used to generate a unique identifier on the password instead. That identifier will have all the properties of the generated key material, including the property that it is impossible to retrieve the input material without a brute force attack. In other words, you can not decrypt the password - you can only try each possible password to see if the output of PBKDF2 matches.