Module: JWA::Algorithms::ContentEncryption::AesCbcHs
- Included in:
- A128CbcHs256, A192CbcHs384, A256CbcHs512
- Defined in:
- lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb
Overview
Abstract AES in CBC mode, with SHA2 signature for different key sizes.
Defined Under Namespace
Modules: ClassMethods
Instance Attribute Summary collapse
-
#iv ⇒ Object
readonly
Returns the value of attribute iv.
-
#key ⇒ Object
readonly
Returns the value of attribute key.
Class Method Summary collapse
Instance Method Summary collapse
- #cipher ⇒ Object
- #cipher_round(direction, data) ⇒ Object
- #decrypt(ciphertext, authenticated_data, tag) ⇒ Object
- #enc_key ⇒ Object
- #encrypt(plaintext, authenticated_data) ⇒ Object
- #generate_tag(authenticated_data, ciphertext) ⇒ Object
- #initialize(key, iv = nil) ⇒ Object
- #mac_key ⇒ Object
Instance Attribute Details
#iv ⇒ Object (readonly)
Returns the value of attribute iv.
8 9 10 |
# File 'lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb', line 8 def iv @iv end |
#key ⇒ Object (readonly)
Returns the value of attribute key.
8 9 10 |
# File 'lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb', line 8 def key @key end |
Class Method Details
.included(base) ⇒ Object
70 71 72 |
# File 'lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb', line 70 def self.included(base) base.extend(ClassMethods) end |
Instance Method Details
#cipher ⇒ Object
66 67 68 |
# 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) ⇒ Object
41 42 43 44 45 46 47 |
# 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) ⇒ Object
30 31 32 33 34 35 36 37 38 39 |
# 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 ⇒ Object
62 63 64 |
# 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) ⇒ Object
23 24 25 26 27 28 |
# 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) ⇒ Object
49 50 51 52 53 54 55 56 |
# 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 |
#initialize(key, iv = nil) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 |
# 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 |
#mac_key ⇒ Object
58 59 60 |
# File 'lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb', line 58 def mac_key @key[0...self.class.key_length / 2] end |