Trouble decrypting a TripleDES hex string with an IV
GoogleCodeExporter opened this issue · 1 comments
GoogleCodeExporter commented
I have a Java server creating a TripleDES-encrypted hex string using CFB and no
padding ("DESede/CFB/NoPadding"). The first 16 bytes of the returned string
are the IV, the rest is the encrypted message. I have months-old ActionScript
production code that successfully decrypts these messages (see code below). I
am trying to port this decryption code to a Node.js server, and haven't had any
luck thus far.
I can't change the Java-side encryption, so I'm stuck with getting decryption
to work somehow with the parameters outlined above.
--
What steps will reproduce the problem?
- This problem isn't directly reproducible, but:
1. I'm just trying to figure out what code to write with crypto-js to do the
same thing that works in ActionScript.
2. I've tried several different ways to write the JS code, and I get garbled
messages every time.
3. I've looked for guidance in your examples, third-party blog entries,
StackOverflow, and your unit tests. There is a lot of talk about how to
encrypt with a custom IV, but I can't find examples of decrypting with a known
IV.
What is the expected output? What do you see instead?
- I expect to be able to decrypt my message given an IV, an encrypted message,
and a shared secret key.
What version of the product are you using? On what operating system?
- NPM tells me I am running crypto-js@3.1.2-2. Currently developing and
testing on Windows 7 on a node.js server.
Please provide any additional information below.
Here is the ActionScript 3 code that works (using AS3Crypto):
private function decryptFrom(encrypted:String):String {
var mode:CFBMode = new CFBMode(new TripleDESKey(Hex.toArray("<hex shared secret here>")));
mode.IV = Hex.toArray(encrypted.substr(0, 16));
var data:ByteArray = Hex.toArray(encrypted.substr(16));
mode.decrypt(data);
return Hex.toString(Hex.fromArray(data));
}
Here is just the latest of many, many attempts in JavaScript (CoffeeScript,
actually, but you get the idea):
_decryptFrom: (encrypted) ->
sharedSecret = '<hex shared secret here>'
hexStringArray = encrypted.split ''
iv = hexStringArray[0..15].join('')
ciphertext = hexStringArray[16..].join('')
# This is just something I tried given a similar issue you answered about AES with IV's. Outdated solution, as it was from 2011?
ciphertextObj = new CryptoJS.Ciphertext(CryptoJS.util.hexToBytes(ciphertext), CryptoJS.util.hexToBytes(iv))
CryptoJS.TripleDES.decrypt(ciphertextObj, sharedSecret, mode: CryptoJS.mode.CFB, padding: CryptoJS.pad.NoPadding).toString(CryptoJS.enc.Latin1)
I've also tried adding the IV to the options hash. I've tried several
combinations of converting the iv, ciphertext, and shared secret (key) from hex
to word arrays.
I've also tried writing a formatter a few different ways, but I can't get that
to work either:
customformatter =
stringify: (cipherParams) ->
cipherParams.iv.toString(CryptoJS.enc.hex) + cipherParams.ciphertext.toString(CryptoJS.enc.hex)
parse: (hexString) ->
hexStringArray = hexString.split ''
CryptoJS.lib.CipherParams.create
iv: CryptoJS.enc.Hex.parse hexStringArray[0..15].join('')
ciphertext: CryptoJS.enc.Hex.parse hexStringArray[16..].join('')
(I realize I'm not using stringify() for decryption -- I will be encrypting
from this app as well, but I'm just trying to decrypt an existing message from
Java first.)
So: Can you give me some crypto-js decryption code that should be the
equivalent of my working ActionScript code?
What I'd really love to see is a couple more tests added to your TripleDES test
suite. One that encrypts (without creating a custom IV) and returns an "IV +
ciphertext" string, and one that decrypts that result, given only that "IV +
ciphertext" string and the shared secret.
Thanks,
Ed
Original issue reported on code.google.com by ed.tram...@gmail.com
on 10 Feb 2014 at 5:17
GoogleCodeExporter commented
Well, never mind and thanks anyway... I gave up on crypto-js, and went back to
Node.js's built-in crypto library (which I gave up on previously because I
mistakenly thought it wouldn't handle CFB, but it does).
Perhaps you'll want to answer my query anyway, in case it helps some of your
other users in the future. (Besides, I'd like to see how close I was to
getting this to work with your library.)
But for those who are stuck like I was, and get here via a search, here is my
Node.js-crypto-based (repeat, NOT crypto-js-based!) code. It decrypts its own
encryptions, as well as the ones from my Java server. (Whew.)
sharedSecret = '<hex shared secret here>'
_encrypt: (string) ->
randomIV = @_generateRandomHexString 16
cipher = crypto.createCipheriv 'des-ede3-cfb', new Buffer(sharedSecret, 'hex'), new Buffer(randomIV, 'hex')
randomIV + cipher.update(string, 'utf8', 'hex') + cipher.final('hex')
_decrypt: (encrypted) ->
hexStringArray = encrypted.split ''
iv = hexStringArray[0..15].join('')
ciphertext = hexStringArray[16..].join('')
decipher = crypto.createDecipheriv 'des-ede3-cfb', new Buffer(sharedSecret, 'hex'), new Buffer(iv, 'hex')
decipher.update(ciphertext, 'hex', 'utf8') + decipher.final('utf8')
Thanks,
Ed
Original comment by ed.tram...@gmail.com
on 10 Feb 2014 at 11:22