class Gibberish::AES::SJCL
Constants
- ALLOWED_KS
- ALLOWED_MODES
- ALLOWED_TS
- DEFAULTS
- MAX_ITER
Public Class Methods
new(password, opts={})
click to toggle source
# File lib/gibberish/aes.rb, line 131 def initialize(password, opts={}) @password = password @opts = DEFAULTS.merge(opts) check_cipher_options(@opts) end
Public Instance Methods
check_cipher_options(c_opts)
click to toggle source
Assume the worst
# File lib/gibberish/aes.rb, line 190 def check_cipher_options(c_opts) if @opts[:max_iter] < c_opts[:iter] # Prevent DOS attacks from high PBKDF iterations # You an increase this by passing in opts[:max_iter] raise CipherOptionsError.new("Iteration count of #{c_opts[:iter]} exceeds the maximum of #{@opts[:max_iter]}") elsif !ALLOWED_MODES.include?(c_opts[:mode]) raise CipherOptionsError.new("Mode '#{c_opts[:mode]}' not supported") elsif !ALLOWED_KS.include?(c_opts[:ks]) raise CipherOptionsError.new("Keystrength of #{c_opts[:ks]} not supported") elsif !ALLOWED_TS.include?(c_opts[:ts]) raise CipherOptionsError.new("Tag length of #{c_opts[:ts]} not supported") elsif c_opts[:iv] && Base64.decode64(c_opts[:iv]).length > 12 raise CipherOptionsError.new("Initialization vector's greater than 12 bytes are not supported in Ruby.") end end
decrypt(h)
click to toggle source
# File lib/gibberish/aes.rb, line 158 def decrypt(h) begin h = JSON.parse(h, {:symbolize_names => true}) rescue => e raise "Unable to parse JSON of crypted text. #{e.inspect}" end check_cipher_options(h) key = OpenSSL::PKCS5.pbkdf2_hmac(@password, Base64.decode64(h[:salt]), h[:iter], h[:ks]/8, 'SHA256') iv = Base64.decode64(h[:iv]) ct = Base64.decode64(h[:ct]) tag = ct[ct.length-h[:ts]/8,ct.length] ct = ct[0,ct.length-h[:ts]/8] cipherMode = "#{h[:cipher]}-#{h[:ks]}-#{h[:mode]}" begin c = OpenSSL::Cipher.new(cipherMode) rescue RuntimeError => e raise "OpenSSL error when initializing: #{e.inspect}" end c.decrypt c.key = key c.iv = iv c.auth_tag = tag; c.auth_data = h[:adata] || "" begin out = c.update(ct) + c.final(); rescue OpenSSL::Cipher::CipherError => e raise DecryptionError.new(e.inspect); end return Plaintext.new(out.force_encoding('utf-8'), h[:adata]) end
encrypt(plaintext, adata='')
click to toggle source
# File lib/gibberish/aes.rb, line 137 def encrypt(plaintext, adata='') salt = SecureRandom.random_bytes(8) iv = SecureRandom.random_bytes(12) key = OpenSSL::PKCS5.pbkdf2_hmac(@password, salt, @opts[:iter], @opts[:ks]/8, 'SHA256') cipherMode = "#{@opts[:cipher]}-#{@opts[:ks]}-#{@opts[:mode]}" c = OpenSSL::Cipher.new(cipherMode) c.encrypt c.key = key c.iv = iv c.auth_data = adata ct = c.update(plaintext) + c.final tag = c.auth_tag(@opts[:ts]/8); ct = ct + tag out = { v: @opts[:v], adata: adata, ks: @opts[:ks], ct: Base64.strict_encode64(ct).encode('utf-8'), ts: tag.length * 8, mode: @opts[:mode], cipher: 'aes', iter: @opts[:iter], iv: Base64.strict_encode64(iv), salt: Base64.strict_encode64(salt) } out.to_json end