module JWA::Algorithms::ContentEncryption::AesCbcHs
Abstract AES in CBC mode, with SHA2 signature for different key sizes.
Attributes
iv[R]
key[R]
Public Class Methods
included(base)
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 70 def self.included(base) base.extend(ClassMethods) end
new(key, iv = nil)
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 10 def initialize(key, iv = nil) @key = key @iv = iv || SecureRandom.random_bytes(16) if @key.length != self.class.key_length raise ArgumentError, "Invalid Key. Expected length: #{self.class.key_length}. Actual: #{@key.length}." end if @iv.length != 16 raise ArgumentError, "Invalid IV. Expected length: 16. Actual: #{@iv.length}." end end
Public Instance Methods
cipher()
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 66 def cipher @cipher ||= Cipher.for(self.class.cipher_name) end
cipher_round(direction, data)
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 41 def cipher_round(direction, data) cipher.send(direction) cipher.key = enc_key cipher.iv = @iv cipher.update(data) + cipher.final end
decrypt(ciphertext, authenticated_data, tag)
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 30 def decrypt(ciphertext, authenticated_data, tag) signature = generate_tag(authenticated_data, ciphertext) if signature != tag raise JWA::BadDecrypt, 'Signature check failed. The AAD may have been tampered.' end cipher_round(:decrypt, ciphertext) rescue OpenSSL::Cipher::CipherError raise JWA::BadDecrypt, 'Invalid ciphertext or authentication tag.' end
enc_key()
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 62 def enc_key @key[self.class.key_length / 2..-1] end
encrypt(plaintext, authenticated_data)
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 23 def encrypt(plaintext, authenticated_data) ciphertext = cipher_round(:encrypt, plaintext) signature = generate_tag(authenticated_data, ciphertext) [ciphertext, signature] end
generate_tag(authenticated_data, ciphertext)
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 49 def generate_tag(authenticated_data, ciphertext) length = [authenticated_data.length * 8].pack('Q>') # 64bit big endian to_sign = authenticated_data + @iv + ciphertext + length signature = OpenSSL::HMAC.digest(self.class.hash, mac_key, to_sign) signature[0...mac_key.length] end
mac_key()
click to toggle source
# File lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb, line 58 def mac_key @key[0...self.class.key_length / 2] end