How to resolve deprecation warnings for OpenSSL::Cipher::Cipher#encrypt
Due to the implicit type conversion in Ruby, older Ruby allows people use PBE (Password-Based Encryption) in a totally wrong way. The newer one fixes that so the warning is a good thing.
Your example shows exactly the problem. Triple-DES requires 24-byte key material (including parity) but you only provided 6 bytes. Your key material will be repeated to make up the deficit, that resulted in a less secure key.
The correct way to do this is to generate key and IV (initial vector) with PKCS5, which use complicated hashing and iteration to make the key much more secure.
Ruby provides following sample code. pass
is your key and you can use any hardcoded value for salt
.
puts "--Encrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.pkcs5_keyivgen(pass, salt)
des.encrypt
cipher = des.update(text)
cipher << des.final
puts %(encrypted text: #{cipher.inspect})
puts
puts "--Decrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.pkcs5_keyivgen(pass, salt)
des.decrypt
out = des.update(cipher)
out << des.final
puts %(decrypted text: "#{out}")
puts
How to fix openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in laravel?
Even though you are using a deprecated way to instantiate your class (using same name instead of __construct method) the sample code you provided is working.
You can improve your class like this.
class DES
{
private $key;
private $iv;
public function __construct(string $key, string $iv = '') {
$this->key = $key;
if(strlen($iv) != 8) {
$this->iv = \Illuminate\Support\Str::random(8);
} else {
$this->iv = $iv;
}
}
public function encrypt($str) {
return base64_encode( openssl_encrypt($str, 'DES-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv ) );
}
}
rails openssl different results of encryption from code and terminal
You provide the key
and iv
attributes as hex strings, but the expected format is raw bytes. Converting them to binary yields the expected result, with the following script:
require 'openssl'
require 'base64'
def hex_to_bin(s)
s.scan(/../).map { |x| x.hex.chr }.join
end
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.encrypt
cipher.key = hex_to_bin("C81E728D9D4C2F636F067F89CC14862C65990ABE58735B91B6B8798E8CE45F22")
cipher.iv = hex_to_bin("D342F9C6310F6B21E97AB38595BD8CAA")
encrypted_data = cipher.update("TestData")
encrypted_data << cipher.final
puts Base64.strict_encode64(encrypted_data)
(Source for the hex_to_bin
function: To Hex and Back (With Ruby)).
Calling it encrypt.rb
, this is the result of running it:
$ ruby encrypt.rb
encrypt.rb:8: warning: constant OpenSSL::Cipher::Cipher is deprecated
VJwJBTtVntJvRGkD24S4wg==
To get rid of the "is deprecated" warning I had to replace the deprecated class OpenSSL::Cipher::Cipher
with OpenSSL::Cipher
.
How do I refactor OpenSSL pkcs5_keyivgen in ruby?
Was trying to solve this problem, but I think there is no easy solution or i just can't see one). Pkcs5_keyivgen()
is deprecated and implements non-standard pass key derivation for AES 256.
From this docs and this source code
Pkcs5_keyivgen (pass, SALT = nil, num = 2048, digest = "MD5") -> nil
Generates some key and IV from salt and pass. No salt in your case. Generation method is defined in v1.5 PKCS #5
(deprecated)
So you are looking for "Password Based Key Derivation Function". PBKDF1
Pkcs5_keyivgen()
function calls EVP_BytesToKey()
from Openssl and EVP_BytesToKey()
generates key bytes for larger key size in a non-standard way
So MD5 generates hash of size EVP_MAX_MD_SIZE (16 + 20)
// 16 for MD5
But AES key(32) + IV(16) sizes > EVP_MAX_MD_SIZE
, so AES 256 will need multiple hashes to generate random key and IV. Here is source code of algorithm in C
And here is nice pseudo-code explanation of the EVP_BytesToKey()
If you really want to re-implement PBKDF1 here is also RTC2898 standard for PBKDF1
But i don't think that it is a good idea to implement crypto yourself
Related Topics
How to Pluck Email from Array of Users
Have Devise Create a Subdomain on Registration
Conditional Haml - If Else Nesting
Change HTML Form Id Generated by Form_For Rails 3.1
"Use" Keyword/Word in Ruby/Rails/Rack Code
Remove Rails Model After Migration
How to Return Correct Http Error Codes from Ruby on Rails Application
Rbenv: Ruby: Command Not Found
Chef and Erb Templates. How to Use Boolean Code Blocks
Split Array Up into N-Groups of M Size
Does Concurrency Happen Even When Only One Thread Is in a Thread Pool
Running Parallel Selenium Tests with Capybara
Connect to Tor Network with Ruby