Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Generating PBKDF2 keys in C# and NodeJS

Generating PBKDF2 keys in C# and NodeJS

Problem

I'm trying to encrypt a Byte array in C# using AES192 and a PBKDF2 password/salt based key and decrypt the same data in NodeJS. However my key generation produces different results in both NodeJS and C#.

The C# code is as follows:

    private void getKeyAndIVFromPasswordAndSalt(string password, byte[] salt, SymmetricAlgorithm symmetricAlgorithm, ref byte[] key, ref byte[] iv)
    {
        Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt);
        key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
        iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
    }

    private byte[] encrypt(byte[] unencryptedBytes, string password, int keySize)
    {
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = keySize;
        aesEncryption.BlockSize = 128;
        byte[] key = new byte[keySize];
        byte[] iv = new byte[128];
        getKeyAndIVFromPasswordAndSalt(password, Encoding.ASCII.GetBytes("$391Ge3%£2gfR"), aesEncryption, ref key, ref iv);
        aesEncryption.Key = key;
        aesEncryption.IV = iv;
        Console.WriteLine("iv: {0}", Convert.ToBase64String(aesEncryption.IV));
        Console.WriteLine("key: {0}", Convert.ToBase64String(aesEncryption.Key));
        ICryptoTransform crypto = aesEncryption.CreateEncryptor();
        // The result of the encryption and decryption            
        return crypto.TransformFinalBlock(unencryptedBytes, 0, unencryptedBytes.Length);
    }

The NodeJS code reads like this:

    crypto.pbkdf2("Test", "$391Ge3%£2gfR", 1000, 192/8, (err, key) => {
        var binkey = new Buffer(key, 'ascii');
        var biniv = new Buffer("R6taODpFa1/A7WhTZVszvA==", 'base64');
        var decipher = crypto.createDecipheriv('aes192', binkey, biniv);
        console.log("KEY: " + binkey.toString("base64"));
        var decodedLIL = decipher.update(decryptedBuffer);
        console.log(decodedLIL);
        return;
    });

The IV is hardcoded as I can't figure out how to calculate that using pbkdf2. I've looked through the nodeJS docs for more help but I'm at a loss as to what's going on here.

Any assistance would be greatly appreciated.

Problem courtesy of: elaverick

Solution

One of the issues I see is the encoding of the pound sign (£). crypto.pbkdf2 encodes the password and salt to a binary array by default, where each character is truncated to the lowest 8 bits (meaning the pound sign becomes the byte 0xA3).

However, your C# code converts the salt to ASCII, where each character is truncated to the lowest 7 bits (meaning the pound sign becomes the byte 0x23). Also it uses the Rfc2898DeriveBytes constructor that takes a String for the password. Unfortunately, the documentation doesn't say what encoding is used to convert the string to bytes. Fortunately, Rfc2898DeriveBytes does have another contructor that takes a byte array for the password and also takes an iteration count parameter, here 1000.

Accordingly, you should convert the password and salt strings to byte arrays by truncating each character to 8 bits, just like Node.js does by default. Here is an example:

var bytes=new byte[password.Length];
for(var i=0;i
Solution courtesy of: Peter O.

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Generating PBKDF2 keys in C# and NodeJS

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×