module Cryptdoh
Constants
- DIGEST
- ITERATIONS
- IV_LENGTH
- KEY_LENGTH
- MIN_PASSWORD_LENGTH
- SALT_LENGTH
- VERSION
Public Class Methods
_check_password_length(password)
click to toggle source
# File lib/cryptdoh.rb, line 66 def self._check_password_length(password) raise UserError, "Crappy password: too short. Must be at least 8 bytes" unless password.size >= MIN_PASSWORD_LENGTH end
_check_password_strength(password)
click to toggle source
# File lib/cryptdoh.rb, line 61 def self._check_password_strength(password) c = CrackLib::Fascist(password) raise UserError, "Crappy password: #{c.reason}" unless c.ok? end
_decode(data)
click to toggle source
# File lib/cryptdoh.rb, line 86 def self._decode(data) Base64.decode64(data) rescue raise EvilError, 'Bad base64 data' end
_encode(data)
click to toggle source
# File lib/cryptdoh.rb, line 82 def self._encode(data) Base64.encode64(data).chomp end
_hmac(key, message)
click to toggle source
# File lib/cryptdoh.rb, line 77 def self._hmac(key, message) # Only require 128 bits of security, so cut in half OpenSSL::HMAC.digest(DIGEST, key, message)[0..15] end
_kdf(password, salt = nil)
click to toggle source
# File lib/cryptdoh.rb, line 70 def self._kdf(password, salt = nil) salt ||= SecureRandom.random_bytes(SALT_LENGTH) raise UserError, "Salt is the wrong size" unless salt.size == SALT_LENGTH key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, ITERATIONS, KEY_LENGTH * 2, DIGEST) [salt, key] end
_verify()
click to toggle source
# File lib/cryptdoh.rb, line 92 def self._verify message = 'this is a secret message' password = 'dZ]av}a]i4qK2:1Z:t |Ju.' decrypt(password, encrypt(password, message)) == message rescue false end
decrypt(password, message)
click to toggle source
# File lib/cryptdoh.rb, line 43 def self.decrypt(password, message) (version, encoded_iv, encoded_salt, encoded_ciphertext, encoded_hmac) = message.split('.') (salt, key) = _kdf(password, _decode(encoded_salt)) cipher_key = key[0..KEY_LENGTH-1] hmac_key = key[KEY_LENGTH..-1] hmac = _hmac(hmac_key, [version, encoded_iv, encoded_salt, encoded_ciphertext].join('.')) raise EvilError, 'Invalid HMAC' unless _decode(encoded_hmac) == hmac decipher = OpenSSL::Cipher::AES.new(KEY_LENGTH * 8, :CBC) decipher.decrypt decipher.iv = _decode(encoded_iv) decipher.key = cipher_key decipher.update(_decode(encoded_ciphertext)) + decipher.final end
encrypt(password, message, args = {})
click to toggle source
# File lib/cryptdoh.rb, line 22 def self.encrypt(password, message, args = {}) _check_password_length(password) _check_password_strength(password) unless args[:skip_strength_check] (salt, key) = _kdf(password) cipher_key = key[0..KEY_LENGTH-1] hmac_key = key[KEY_LENGTH..-1] cipher = OpenSSL::Cipher::AES.new(KEY_LENGTH * 8, :CBC) cipher.encrypt iv = cipher.random_iv cipher.key = cipher_key ciphertext = cipher.update(message) + cipher.final cipher_message = [VERSION, _encode(iv), _encode(salt), _encode(ciphertext)].join('.') hmac = _hmac(hmac_key, cipher_message) [cipher_message, _encode(hmac)].join('.') end