Ruby encryption
mouse 2036 · person cloud · link
Last update
2023-08-28
2023
08-28
«notes for an eventual ruby fuse gpg encFs»

AES-256-CBC openssl compatible example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env ruby
require 'openssl'
require 'base64'

plain = "hello world"

puts '----- ENCODE ---------------------------------------------------------------'

# https://stackoverflow.com/questions/32346466/encrypt-file-with-ruby-openssl-and-decrypt-with-command-line
cipher = OpenSSL::Cipher.new('AES-256-CBC').encrypt
cipher.iv = iv = cipher.random_iv

# https://ruby-doc.org/stdlib-2.4.3/libdoc/openssl/rdoc/OpenSSL/PKCS5.html
pass    = "foobar"
salt    = OpenSSL::Random.random_bytes(16)
iter    = 20000
key_len = cipher.key_len #16
digest  = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, key_len, digest)

cipher.key = key

puts "salt = #{salt.unpack('H*').first}"
puts "key  = #{key .unpack('H*').first}"
puts "iv   = #{iv  .unpack('H*').first}"

encrypted = cipher.update plain
encrypted << cipher.final
encrypted_b64 = Base64.strict_encode64 encrypted

puts  "ruby enc = #{encrypted_b64}"
print "ossl enc = "
system "echo -n #{plain} | openssl enc -aes-256-cbc -iv #{iv.unpack('H*').first} -K #{key.unpack('H*').first} -e | base64"

puts '----- DECODE ---------------------------------------------------------------'
cipher = OpenSSL::Cipher.new('AES-256-CBC').decrypt
cipher.iv  = iv
cipher.key = key

puts  "ruby dec = #{cipher.update(encrypted) + cipher.final}"
print "ossl dec = "
system "echo -n #{encrypted_b64} | base64 -d | openssl enc -aes-256-cbc -iv #{iv.unpack('H*').first} -K #{key.unpack('H*').first} -d"

Simple string encoding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# https://stackoverflow.com/questions/11044324/how-to-encrypt-files-with-ruby
# https://ruby-doc.com/stdlib/libdoc/openssl/rdoc/OpenSSL/Cipher.html#class-OpenSSL::Cipher-label-Encrypting+and+decrypting+some+data
#   p = String.aes_params
#   'test'.aes_encrypt(**p).aes_decrypt(**p)
module StringUtils
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    # get random params for encryption
    def aes_params
      cipher = OpenSSL::Cipher::AES.new(256, :CBC)
      cipher.encrypt
      { key: cipher.random_key, iv: cipher.random_iv }
    end # aes_params
  end # ClassMethods

  def aes_encrypt(key:, iv:)
    cipher = OpenSSL::Cipher::AES.new(256, :CBC)
    cipher.encrypt
    cipher.key = key
    cipher.iv  = iv
    cipher.update(self) + cipher.final
  end # aes_encrypt

  def aes_decrypt(key:, iv:)
    decipher = OpenSSL::Cipher::AES.new(256, :CBC)
    decipher.decrypt
    decipher.key = key
    decipher.iv  = iv
    decipher.update(self) + decipher.final
  end # aes_decrypt

  def b64_encode = Base64.strict_encode64(self)
  def b64_decode = Base64.strict_decode64(self)
end

String.send :include, StringUtils