Last active
April 8, 2022 09:46
-
-
Save kkosuge/4d09f014a8f8dc8aa365 to your computer and use it in GitHub Desktop.
PHP <=> Ruby ( OpenSSL AES-256-CBC )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
const PASSWORD = '!!!!!sufficiently_long_password!!!!!'; | |
const CIPHER_METHOD = 'AES-256-CBC'; | |
function encrypt($str) { | |
$iv_length = openssl_cipher_iv_length(CIPHER_METHOD); | |
$iv = mcrypt_create_iv($iv_length, MCRYPT_RAND); | |
$str = $iv.$str; | |
$val = openssl_encrypt($str, CIPHER_METHOD, PASSWORD, 0, $iv); | |
return str_replace(array('+', '/', '='), array('_', '-', '.'), $val); | |
} | |
function decrypt($str) { | |
$val = str_replace(array('_','-', '.'), array('+', '/', '='), $str); | |
$data = base64_decode($val); | |
$iv_length = openssl_cipher_iv_length(CIPHER_METHOD); | |
$body_data = substr($data, $iv_length); | |
$iv = substr($data, 0, $iv_length); | |
$base64_body_data = base64_encode($body_data); | |
return openssl_decrypt($base64_body_data, CIPHER_METHOD, PASSWORD, 0, $iv); | |
} | |
$plain_data = 'secret text'; | |
$encrypted = encrypt($plain_data); | |
$decrypted = decrypt($encrypted); | |
echo $encrypted."\n"; | |
echo $decrypted."\n"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'openssl' | |
require 'base64' | |
require 'pry' | |
PASSWORD = '!!!!!sufficiently_long_password!!!!!'; | |
CIPHER_METHOD = 'AES-256-CBC' | |
def encrypt(str) | |
cipher = OpenSSL::Cipher.new(CIPHER_METHOD) | |
cipher.encrypt | |
iv = OpenSSL::Random.random_bytes(cipher.iv_len) | |
cipher.iv = iv | |
cipher.key = PASSWORD | |
str = iv + str | |
data = cipher.update(str) + cipher.final | |
Base64.urlsafe_encode64(data) | |
end | |
def decrypt(str) | |
data = Base64.urlsafe_decode64(str) | |
cipher = OpenSSL::Cipher.new(CIPHER_METHOD) | |
cipher.decrypt | |
cipher.key = PASSWORD | |
cipher.iv = data[0..(cipher.iv_len-1)] | |
data_body = data[cipher.iv_len..-1] | |
cipher.update(data_body) + cipher.final | |
end | |
plain_data = 'secret text'; | |
encrypted = encrypt(plain_data) | |
decrypted = decrypt(encrypted) | |
puts encrypted | |
puts decrypted |
You don't need to string replace, you just need to use strict_encode64
and strict_decode64
on the ruby side instead of the urlsafe variants.
Thank you. Just a quick note. As off ruby 2.4 plain text password stopped being supported. Its required a 32 bytes password which I generated using key = SecureRandom.random_bytes(32)
.
To store it (on .env file i.e) I base64 encoded it using Base64.encode64(key)
, Then when decypting just decode it using cipher.key = Base64.decode64(key)
.
On PHP side is base64_decode($key);
And all works now 👍
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If the goal is to allow PHP to encode and RUBY to decode, and vice versa, it is important to note a few things.
The encrypt/decrypt functions in RUBY need to add the same str_replace functions usings gsub:
$val = str_replace(array('_','-', '.'), array('+', '/', '='), $str);
In addition, with the current setup, the variable PASSWORD must be 32 characters long or RUBY will complain.