3

I am migrating some server-side Java code to a new NodeJS server. I am looking for an equivalent method call in Javascript to Java's Cipher.doFinal(byte[]) Note that I can't use NodeJS Buffers because they don't support negative Byte values. So to do my encryption, I'll need a method that accepts an array of positive and negative numbers.

Here's all of what I currently have that is related to this problem:

Node JS / Javascript:
var crypto = require('crypto'); var cipher = crypto.createCipher('aes256',key);

Java (javax.crypto.Cipher):

Cipher cipher;
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
try {
    cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
} catch (NoSuchPaddingException e) {
}try {
      cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
} catch (InvalidKeyException e) {
}

later in the Java code, I call this method where Iv represents Initialization Vector: byte[] newIv = cipher.doFinal(myIv);

How can I get the same result in JavaScript as I do in the doFinal Java method?

2 Answers 2

3

Byte handling

You can use NodeJS buffers. The byte arrays in Java may just consist of signed bytes, but those bytes are not handled any differently from unsigned bytes. Only the value of the actual bits matter. If you need to treat bytes directly, it is often best to use hexadecimals instead. You can convert to an positive integer value by performing b & 0xFF and you can do the opposite by performing (byte) b.

You could of course also do something similar in NodeJS to make NodeJS handle signed numbers, but it is common to treat keys, IV's etc. as unsigned.

Cipher selection

Now for the Java AES encryption, you are using the unsafe "AES/ECB/PKCS5Padding" mode, as the Oracle Java JCE provider defaults to ECB mode of encryption and PKCS#7 padding (incorrectly named "PKCS5Padding" by Java). ECB does not use an IV, so you can ignore the value of the IV. Strangely enough, you do have to use crypto.createCipheriv(algorithm, key, iv) as the crypto.createCipher(algorithm, password) uses a password instead of a key. Of course you should also use algorithm "AES-256-ECB" for NodeJS/OpenSSL - if your key is indeed 256 bits in size.

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

9 Comments

I've left out the actual writing to the NodeJS cipher stream. That should be relatively simple once you've created the right algorithm and keys. You should migrate to a more secure protocol (TLS for preference if you need transport level security).
I think there are some areas in my code where bit manipulation on the negative bytes (signed bytes) comes out differently than their unsigned counterparts. You can't cast as a byte in JS. How would I make NodeJS handle signed numbers? I am using a specific AES custom encryption for a game, both of which I found online. The IV associated with this AES is 4 bytes long so var cipher = crypto.createCipheriv('aes256',key,iv); is returning invalid IV length... Also, this AES requires me to refresh the IV every so often as in the "newIv" Java code above which I need in JS.
I am trying to write someone else's server code in Javascript/Node for educational reasons. Specifically, I'm trying to write the crypt method in this class xp-dev.com/svn/MapleGame/Common/Security/AesCryptograph.cs
Or even in the same method in this class in Java: svn6.assembla.com/svn/MoopleDEV/src/tools/MapleAESOFB.java If you're wondering, I'm making a server for a old MMORPG client so there are a few sources online.
This answer was helpful but didn't answer the question entirely. Actual writing to the NodeJS cipher stream wasn't easy to figure out as I am also a NodeJS noob. The more in-depth the better when you help noobs in the future :)
|
2

Turns out you can place an empty IV as follows:

var cipher = require('crypto').createCipheriv('aes-256'ecb', key, '');

As for the replacement method, simply store your old IV temporarily as a new IV and then attempt to update that new IV using the old one. Here's how it would look like in NodeJS using some of the above code on Initialization Vectors created as buffers:
var newIV = oldIV.slice(); newIV = cipher.update(newIV); oldIV = newIV;

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.