Ad

AES Encryption In Node.js And Decryption On Scala

- 1 answer

I'm trying to decrypt AES on Scala (using javax.crypto.Cipher), the ciphertext was encrypted in Node.js app (using aes-js). and getting an error

  • I'm using Electronic Codebook

Node (encryption)

var aesjs = require("aes-js");

// An example 128-bit key
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
var key_128_array = new Uint8Array(key);

var key_128_hex = aesjs.utils.hex.fromBytes(key_128_array);
console.log(key_128_hex);
// 0102030405060708090a0b0c0d0e0f10


// Convert text to bytes
var text = 'TextMustBe16Byte';
var textBytes = aesjs.utils.utf8.toBytes(text);

var aesEcb = new aesjs.ModeOfOperation.ecb(key_128_array);
var encryptedBytes = aesEcb.encrypt(textBytes);

// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "a7d93b35368519fac347498dec18b458"

Scala (decryption)

import org.bouncycastle.jce.provider.BouncyCastleProvider
import javax.crypto.Cipher

val cipher = Cipher.getInstance("AES", new BouncyCastleProvider())

val key = "0102030405060708090a0b0c0d0e0f10";
val aesKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES")
cipher.init(Cipher.DECRYPT_MODE, aesKeySpec)

val msg = "a7d93b35368519fac347498dec18b458"
val decrypted = cipher.doFinal(msg.getBytes())
log.debug(s"decrypted data ${decrypted}")

And I'm getting the following error:

javax.crypto.BadPaddingException: pad block corrupted
        at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal(Unknown Source)
        at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
        at javax.crypto.Cipher.doFinal(Cipher.java:2164)
...

Any idea what I'm doing wrong? Any help would be greatly appreciated.

Ad

Answer

The problem is with the key and message formats. Key is represented as hex sting and calling .getBytes will return bytes of chars in UTF-8 and not actual key bytes. Java 8 has javax.xml.bind.DatatypeConverter that can convert a hex string into correct Array[Byte]. Same with msg, it has to be converted correctly into Array[Byte]

You have to specify cipher AES/ECB/NoPadding as you do use ecb in node-js.

import javax.crypto.spec.SecretKeySpec
import javax.xml.bind.DatatypeConverter

object DecryptApp extends App {

  import org.bouncycastle.jce.provider.BouncyCastleProvider
  import javax.crypto.Cipher

  val cipher = Cipher.getInstance("AES/ECB/NoPadding", new BouncyCastleProvider())

  val key = "0102030405060708090a0b0c0d0e0f10"
  val keyBytes = DatatypeConverter.parseHexBinary(key)
  val aesKeySpec = new SecretKeySpec(keyBytes, "AES")
  cipher.init(Cipher.DECRYPT_MODE, aesKeySpec)

  val msg = "a7d93b35368519fac347498dec18b458"
  val decrypted = cipher.doFinal(DatatypeConverter.parseHexBinary(msg))
  println(s"decrypted data ${decrypted.map(_.toChar).mkString}")

}
Ad
source: stackoverflow.com
Ad