I am using eccrypto library in javascript for encryption using the ECIES algorithm (curve- secp256k1). The cipher generated by encryption in JS code could not be decrypted in Kotlin.
Here is the Javascript code.
var eccrypto = require("eccrypto");
eccrypto.encrypt(publicKeyA, Buffer.from("Sic Mundus Creatus Est")).then(function(encrypted) {
val ciphertext = encrypted.ciphertext
//the hex encoded ciphertext is then sent to the server
}
Here is the decryption code for kotlin
val cipherBytes = DatatypeConverter.parseHexBinary(ciphertext)
val cipher: Cipher = Cipher.getInstance("ECIES", "BC")
cipher.init(Cipher.DECRYPT_MODE, privateKeyA)
print( cipher.doFinal(cipherBytes) )
With this code for decryption, I get an Bad Block Exception.
However, if I just do encryption and decryption using Java, there is no problem. Also, encryption and decryption both in Javascript also work fine.
Is there anything I am missing?
I found the solution (or say figured out the actual issue). Hope it helps future devs:
The mismatch in encryption/decryption between javascript and java implementation is because those implementations are using different parameters of the hash algorithm and AES encryption.
ECIES implementation in Java using BouncyCastle has a crappy implementation. It uses AES with 128 bits, does not use a secure hash algorithm, no robust check for MAC, and has very little test cases.
As a workaround, I now use a custom written ECIES implementation for Java which uses SHA-512 for the hash, AES encryption (using 256 bits key and AES/CBC/PKCS7Padding mode). This new implementation is what eccrypto
javascript library engine uses under the hood. Now, they work fine!