3

I'm trying to encrypt some data in Mono C#, send it to a NodeJS server and decrypt it there. I'm trying to figure out what algorithms to use to match the two.

I send the encrypted string encoded with base64. So I do something like this in Javascript, where I know the key which was used to encrypt the data in my C# application:

var decipher = crypto.createDecipher('aes192',binkey, biniv);
var dec = decipher.update(crypted,'base64','utf8');
dec += decipher.final('utf8');
console.log("dec", dec);

In Mono I create my Cypher with:

using System.Security.Cryptography;
using (Aes aesAlg = Aes.Create("aes192"))

I need to pass the correct string to Aes.Create() in order to have it use the same algorithm, but I can't find what it should be. "aes192" is not correct it seems.

I don't need aes192 this was just a tryout. Suggest a different encryption flavor if it makes sense. Security is not much of an issue.

Here are links to .NET and Nodejs docs: http://msdn.microsoft.com/en-us/library/system.security.cryptography.aes.aspx http://nodejs.org/api/crypto.html

4
  • What are you protecting in what kind of situation? I think you might be better off using TLS in this case. Commented Jun 26, 2013 at 6:37
  • Since your issue seems to be .net, not the js. How about starting with an AES Then HMac or AES-GCM in c# stackoverflow.com/a/10366194/637783 and then work out your JS. Commented Jun 26, 2013 at 13:20
  • @ntoskrnl I'm using this for challenge response pattern for license activation. Commented Jun 27, 2013 at 10:11
  • @jbtule encryption/decryption in c# is fine with the referenced example code. So I already have an encrypted string, it's just that I can't decrypt it on the Node.js side. Commented Jun 27, 2013 at 10:12

3 Answers 3

1

This code works for my Node.js side, but please replace the static iv, otherwhise aes encryption would be useless.

var crypto = require('crypto');

function encrypt(data, key) {
    key = key || new Buffer(Core.config.crypto.cryptokey, 'binary'),
        cipher = crypto.createCipheriv('aes-256-cbc', key.toString('binary'), str_repeat('\0', 16));
    cipher.update(data.toString(), 'utf8', 'base64');
    return cipher.final('base64');
}

function decipher(data, key) {
    key = key || new Buffer(Core.config.crypto.cryptokey, 'binary'),
        decipher = crypto.createDecipheriv('aes-256-cbc', key.toString('binary'), str_repeat('\0', 16));
    decipher.update(data, 'base64', 'utf8');
    return decipher.final('utf8');
}

function str_repeat(input, multiplier) {
    var y = '';
    while (true) {
        if (multiplier & 1) {
            y += input;
        }
        multiplier >>= 1;
        if (multiplier) {
            input += input;
        } else {
            break;
        }
    }
    return y;
}

I hope this helps You.

NOTE: You need to deliver an 265bit aka 32 character key for this algorithm to work.

POSSIBLE .NET SOLUTION: This may help you Example

Sign up to request clarification or add additional context in comments.

2 Comments

Great! It's been a while since I was trying to do this, but I still needed to get back to this :)
Nice that it helped you.
0

You should simply write new AesManaged().
You don't need to call Create().

You then need to set Key and IV, then call CreateDecryptor() and put it in a CryptoStream.

6 Comments

Well ok so you can write the code differently, but I know how to do the encryption with the key and IV. My question was how do I choose what AES flavor, so I can match it in Node.js for decryption. Or am I missing something?
In the meantime I've learned that the number is the key size, and you can query it from the aes object in c# with KeySize, it turns out to be 256 bytes. Still when I try 'aes-256-cbc' or 'aes-256' in nodejs I get this error TypeError: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length. Going to investigate further...
@0x80 You need to match the mode of operation and the padding on both sides. It helps to specify them explicitly so as not to rely on implementation specific behavior.
CryptoStream is only useful for large amounts of data where you don't want the whole input/output in a single array.
@ntoskrnl Any hints to where/how I can specify the padding and mode of operation? The NodeJS crypto modules doesn't seem to reference them for example.
|
0

It turned out to be a stupid mistake. I thought the create function in Node.js could take a variable argument count. Turns out you need to call the createDecipheriv() instead.

Just for the record, you can easily check the padding and mode by looking at those properties in the Aes object. The defaults are CBC and PKCS7. That padding is also used in nodejs crypto. So a for a 128 key size my code to decrypt a base64 encoded string would be:

var crypto = require('crypto');
var binkey = new Buffer(key, 'base64');
var biniv = new Buffer(iv, 'base64');
var decipher = crypto.createDecipheriv('aes-128-cbc', binkey, biniv);
var decrypted = decipher.update(crypted,'base64','utf8');
decrypted += decipher.final('utf8');
console.log("decrypted", decrypted);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.