I have a Node.js API. It has to make a SOAP call to a "parent" API that includes one item encrypted via AES-192 (ECB) with a key. I'm trying to use the native crypto library, but the value I'm getting doesn't match the value they're expecting.
From the spec:
Encryption of the [string] is done using AES (NIST FIPS-197) 192 bit encryption using Hex encoding. It uses the ECB feedback mode with PKCS5Padding. Neither IV nor salting is used.
Frankly, I had to look most of that up and it still hasn't helped. Aside from occasionally md5'ing something that didn't need to be truly secure or perhaps sha'ing something that did, I've never done much with encryption so I'm a little stuck. Here's what I have at this point:
var cipher = require( 'crypto' ).createCipher( 'aes192', datasources.api.auth.encryptionKey )
cipher.update( data.encryptable )
cipher.final( 'hex' )
I've tried a number of variants of input and output encoding in cipher.update(), but I haven't been able to match the value that they're expecting.
Can anyone more familiar with this stuff point me in the right direction? At this point, I've exhausted my own knowledge and have digressed into trial and error.
UPDATE
More of what I have so far:
var crypto = require( 'crypto' );
var cipher = crypto.createCipher( 'aes-192-ecb', datasources.api.auth.encryptionKey );
var crypted = cipher.update( 'DSS9676155', 'binary', 'hex' );
crypted += cipher.final( 'hex' );
console.log( 'CRYPTED: ' + crypted );
console.log( 'EXPECTED: 72989ABBE3D58AE582EF0EA669EDE521' );
Interestingly (?), I get the same crypted value (164fb25126c444031780c78d098fa877) no matter what combination of input and output encoding values I send to the update() method. That seems like a clear indication that I've done something very wrong, but I can't see it.
UPDATE
Just received this from the API provider. They encrypt the text using Python as follows:
import sys
import chilkat
crypt = chilkat.CkCrypt2()
password = "thisIsWhereTheKeyGoes"
crypt.put_CryptAlgorithm("aes")
crypt.put_CipherMode("ECB")
crypt.put_KeyLength(192)
crypt.SetEncodedKey(password,"base64")
crypt.put_EncodingMode("hex")
text = "The string to be encrypted"
encText = crypt.encryptStringENC(text)
print encText
I've updated my code as follows:
var crypto = require( 'crypto' );
var base64pwd = new Buffer( datasources.api.auth.encryptionKey ).toString( 'base64' );
var cipher = crypto.createCipher( 'aes-192-ecb', base64pwd );
var crypted = cipher.update( 'DSS9676155', 'utf8' );
crypted += cipher.final( 'hex' );
console.log( 'CRYPTED: ' + crypted );
console.log( 'EXPECTED: 72989ABBE3D58AE582EF0EA669EDE521' );
I still a different result from what's expected. Again, I've tried several variants of in/output encoding.
For whatever it's worth, I never got Node.js to kick back the same value that the provider expected. I ended up writing a Python script using the same process they use and had my Node app call it. It's a total hack, but at least it works.
Just wanted to put a wrapper on this question so it wasn't left open forever.
The following code works for me:
var crypto = require( 'crypto' );
var cipher = crypto.createCipheriv('aes-256-cbc', DATA_CRYPT_KEY, DATA_CRYPT_IV);
var crypted = cipher.update(JSON.stringify(result),'utf8','hex');
crypted += cipher.final('hex');
res.send(crypted);