I've been using lazysodium-java
(a wrapper for libsodium
) to encrypt/decrypt certain information. I noticed some inconsistent behavior and created a test and found that indeed, for the same input, I will sometimes get a failure to decrypt an encrypted message. I am wondering if I am somehow using the library wrong? As far as I can tell, it should be consistent and thread-safe.
Here's an example of a test that reproduces the issue (Scala), fails at different iterations (i
) each time (when cryptoSecretBoxOpenEasy
fails it returns false and doesn't update the given message):
test("Decrypt you fool") {
// encrypt a message
val nonceSize = SecretBoxModule.NONCEBYTES
val secret = SecretKey("secret")
val nonce = lazySodium.nonce(nonceSize)
val secretMessage = "catcher"
val messageToEncrypt = secretMessage.getBytes(StandardCharsets.UTF_8)
val cipher = new Array[Byte](messageToEncrypt.length + SecretBoxModule.MACBYTES)
lazySodium.cryptoSecretBoxEasy(cipher, messageToEncrypt, messageToEncrypt.length, nonce, secret.keyBytes)
val encrypted = nonce ++ cipher
// loop 1000 times to decrypt message
for (i <- 1 to 1000) {
println(s"Running $i")
val message = new Array[Byte](encrypted.length - SecretBoxModule.MACBYTES - nonceSize)
val (nonce, cipherText) = encrypted.splitAt(nonceSize)
secretBoxModule.cryptoSecretBoxOpenEasy(message, cipherText, cipherText.length, nonce, secret.keyBytes)
val response = new String(message, StandardCharsets.UTF_8)
scala.Predef.assert(response == secretMessage)
}
assertCompletes
}
Any idea why the inconsistent decryption behavior?
I expected this to consistently decrypt my message successfully, but it actually fails every once in a while, despite the input not changing.
I found the issue: according to the docs, the secret key used for encryption must be 32 bytes (256 bits) long. In my tests I used dummy keys that did not meet this requirements which causes unexpected behavior.