0

I have this project wherein I have to convert nodeJs into Kotlin. The nodeJs project uses CryptoJS.AES.encrypt(text, password) which produces a encrypted value with 256 bytes. I. have been doing this in kotlin but the encrypted value returned is not the same from the nodeJs version and it only has 236 bytes. Can someone help me why it is not producing the same result? and how can i do it? Below is my sample code in kotlin

fun encryptAesTry(text: String, password: String): String {

    val md = MessageDigest.getInstance("SHA-256")
    val bytes = password.toByteArray(StandardCharsets.UTF_8)
    md.update(bytes, 0, bytes.size)
    val key = md.digest()
    val secretKeySpec = SecretKeySpec(key, "AES")
    val c = Cipher.getInstance("AES")
    c.init(Cipher.ENCRYPT_MODE, secretKeySpec)
    val encVal = c.doFinal(text.toByteArray())
            
    return Base64.getEncoder().encodeToString(encVal)

}
juju11
  • 17
  • 4
  • 1
    With CryptoJS, the processing logic depends on the data type of the key material. Therefore, you must specify whether `password` in the CryptoJS code is a string or `WordArray`. If it is a string, the key derivation via `EVP_BytesToKey()` is missing in the Kotlin code. – Topaco Dec 07 '22 at 09:51
  • I do not know exactly how to do EVP_BytesToKey() in kotlin, that is why i just generated my own key form my password using messageDigest – juju11 Dec 07 '22 at 09:52
  • You can find ports of `EVP_BytesToKey()` for various languages on the web (for Kotlin I' m not sure, but at least for Java). A convenient alternative is BouncyCastle, see e.g. this example [here](https://stackoverflow.com/a/74602441/9014097) for a decryption with Java. – Topaco Dec 07 '22 at 10:14
  • @Topaco+ and cryptojs.Cipher.encrypt (with EVP_BytesToKey) is randomized using 'salt', as is required on all modern encryption (like AES) for semantic security, so if you encrypt the same data with the same pw many times, whether in the same language or different languages, you get a different result every time -- all of which are _correct_ -- and **you can't check modern encryption by comparing ciphertexts**. Instead it either decrypts correctly, or not; some modes like CBC use padding which provides a (very) limited error check. The salt also makes the ciphertext longer, as you saw. – dave_thompson_085 Dec 07 '22 at 14:00
  • @dave_thompson_085 - *...you can't check modern encryption by comparing ciphertexts...* For testing, random values can be temporarily replaced by static ones, so I don't agree with this formulation. The details of the CryptoJS encryption logic, especially the random salt, the format etc. are described in the post I linked (and a bunch of others). – Topaco Dec 07 '22 at 14:53
  • thank you @dave_thompson_085! that really helped me, but do the kotlin and javascript output has the same format? because i need to extract some strings like perform substring(11, 20), substring(21, 29), etc.. and im trying to trim the strings in kotlin for authentication but it wont work – juju11 Dec 09 '22 at 06:20

0 Answers0