Skip to content

cipher: remove Cipher#encrypt(password, iv) form #887

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

Merged
merged 1 commit into from
May 15, 2025

Conversation

rhenium
Copy link
Member

@rhenium rhenium commented May 13, 2025

OpenSSL::Cipher#encrypt and #decrypt have long supported a hidden feature to derive a key and an IV from the String argument, but in an inappropriate way.

This feature is undocumented, untested, and has been deprecated since Ruby trunk r6549 on 2004-06-30, which started printing a non-verbose warning. More than 20 years later, it must be safe to remove it entirely.

The deprecated usage:

# `password` is a String, `iv` is either a String or nil
cipher = OpenSSL::Cipher.new("aes-256-cbc")
cipher.encrypt(password, iv)
p cipher.update("data") << cipher.final

was equivalent to:

cipher = OpenSSL::Cipher.new("aes-256-cbc")
cipher.encrypt

iv ||= "OpenSSL for Ruby rulez!"
key = ((cipher.key_len + 15) / 16).times.inject([""]) { |ary, _|
  ary << OpenSSL::Digest.digest("MD5", ary.last + password + iv[0, 8].ljust(8, "\0"))
}.join
cipher.key = key[...cipher.key_len]
cipher.iv = iv[...cipher.iv_len].ljust(cipher.iv_len, "\0")
p cipher.update("data") << cipher.final

OpenSSL::Cipher#encrypt and #decrypt have long supported a hidden
feature to derive a key and an IV from the String argument, but in an
inappropriate way.

This feature is undocumented, untested, and has been deprecated since
commit ruby/ruby@0dc4321 on 2004-06-30,
which started printing a non-verbose warning. More than 20 years later,
it must be safe to remove it entirely.

The deprecated usage:

	# `password` is a String, `iv` is either a String or nil
	cipher = OpenSSL::Cipher.new("aes-256-cbc")
	cipher.encrypt(password, iv)
	p cipher.update("data") << cipher.final

was equivalent to:

	cipher = OpenSSL::Cipher.new("aes-256-cbc")
	cipher.encrypt

	iv ||= "OpenSSL for Ruby rulez!"
	key = ((cipher.key_len + 15) / 16).times.inject([""]) { |ary, _|
	  ary << OpenSSL::Digest.digest("MD5", ary.last + password + iv[0, 8].ljust(8, "\0"))
	}.join
	cipher.key = key[...cipher.key_len]
	cipher.iv = iv[...cipher.iv_len].ljust(cipher.iv_len, "\0")
	p cipher.update("data") << cipher.final
@rhenium rhenium force-pushed the ky/cipher-remove-encrypt-arg-password branch from 97b6c59 to e46d992 Compare May 13, 2025 17:29
@rhenium rhenium merged commit 1b34bb2 into ruby:master May 15, 2025
40 of 41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant