Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto module can sometimes decrypt with the wrong key #8597

Closed
nathanl opened this issue Jun 19, 2024 · 2 comments
Closed

crypto module can sometimes decrypt with the wrong key #8597

nathanl opened this issue Jun 19, 2024 · 2 comments
Assignees
Labels
not a bug Issue is determined as not a bug by OTP team:VM Assigned to OTP team VM

Comments

@nathanl
Copy link
Contributor

nathanl commented Jun 19, 2024

Describe the bug
I'm not actually sure if this is a bug.

:crypto.crypto_one_time/4 will generally raise an error if given the wrong key for decryption. That's the behavior I expect.

But for some combinations of plaintext and incorrect decryption key, it will seem to decrypt successfully, except that the returned text will not be the same as the plaintext.

To Reproduce
Please forgive the Elixir code snippet.

encryption_key = <<240, 94, 230, 64, 244, 27, 127, 130, 109, 35, 244, 119, 228, 205, 130, 224, 248, 5, 159, 28, 180, 131, 13, 41, 205, 230, 57, 212, 46, 208, 55, 62>>
alt_key = <<193, 172, 221, 62, 186, 65, 168, 72, 56, 184, 55, 251, 61, 133, 57, 128, 104, 135, 15, 104, 32, 233, 205, 134, 0, 98, 132, 136, 74, 23, 124, 192>>
wrong_key = <<156, 101, 205, 112, 217, 30, 254, 204, 123, 252, 209, 32, 233, 93, 88, 250, 61, 250, 198, 149, 5, 135, 23, 231, 21, 11, 75, 125, 59, 193, 74, 0>>

plaintext = "൹ǚ᯷➠Ǡതጻᴣđƒ֧☏ኪⱫ᏷Ɠྃࠫ࢔໩Ȳ◈ࣲầ⭗ⓩώ␔ᙷ┧ۅდࡘ⏾"
ciphertext = :crypto.crypto_one_time(:aes_256_ecb, encryption_key, plaintext,
  encrypt: true,
  padding: :pkcs_padding
)

decrypted = :crypto.crypto_one_time(:aes_256_ecb, encryption_key, ciphertext,
  encrypt: false,
  padding: :pkcs_padding
)

# decrypted is the same as plaintext
IO.inspect ["decrypted correctly with encryption key?", plaintext == decrypted]

decrypted = :crypto.crypto_one_time(:aes_256_ecb, alt_key, ciphertext,
  encrypt: false,
  padding: :pkcs_padding
)

# decrypted isn't the same as plaintext, but also doesn't raise an error
IO.inspect ["decrypted correctly with alt key?", plaintext == decrypted]

# raises an ErlangError error like most wrong keys will
# ** (ErlangError) Erlang error: {:error, {~c"api_ng.c", 634}, ~c"Can't finalize"}
:crypto.crypto_one_time(:aes_256_ecb, wrong_key, ciphertext,
  encrypt: false,
  padding: :pkcs_padding
)

Expected behavior
I expected that an error would be raised anytime a key is given which is not the one the text was encrypted with. (I don't know if this expectation is itself correct, but I don't know how else to detect "wrong key".)

Affected versions
Tested with 27.0 and 26.2.5

@nathanl nathanl added the bug Issue is reported as a bug label Jun 19, 2024
@frej
Copy link
Contributor

frej commented Jun 20, 2024

Encryption by itself does not provide any guarantees for integrity nor authentication. This is an unfortunately a common misconception. You need to use, for example, AES-GCM to get that.

[edit:] This seems like a good explanation.

@jhogberg jhogberg added not a bug Issue is determined as not a bug by OTP and removed bug Issue is reported as a bug labels Jun 20, 2024
@jhogberg jhogberg self-assigned this Jun 20, 2024
@jhogberg jhogberg added the team:VM Assigned to OTP team VM label Jun 20, 2024
@jhogberg
Copy link
Contributor

What @frej said :-)

That you get any exceptions at all is an accident of the padding scheme being used. The padding can be obviously screwed up after being decrypted with the wrong key in which case an error is thrown, but it's fairly likely to look okay in which case you get a garbage return value instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not a bug Issue is determined as not a bug by OTP team:VM Assigned to OTP team VM
Projects
None yet
Development

No branches or pull requests

3 participants