Class: Sandal::Enc::ACBC_HS
- Inherits:
-
Object
- Object
- Sandal::Enc::ACBC_HS
- Defined in:
- lib/sandal/enc/acbc_hs.rb
Overview
Base implementation of the A*CBC-HS* family of encryption methods.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#alg ⇒ Object
readonly
The JWA algorithm used to encrypt the content master key.
-
#name ⇒ Object
readonly
The JWA name of the encryption method.
Instance Method Summary collapse
-
#decrypt(token) ⇒ String
Decrypts an encrypted JSON Web Token.
-
#encrypt(header, payload) ⇒ String
Encrypts a token payload.
-
#initialize(name, aes_size, sha_size, alg) ⇒ ACBC_HS
constructor
Initialises a new instance; it’s probably easier to use one of the subclass constructors.
Constructor Details
#initialize(name, aes_size, sha_size, alg) ⇒ ACBC_HS
Initialises a new instance; it’s probably easier to use one of the subclass constructors.
22 23 24 25 26 27 28 29 |
# File 'lib/sandal/enc/acbc_hs.rb', line 22 def initialize(name, aes_size, sha_size, alg) @name = name @aes_size = aes_size @sha_size = sha_size @cipher_name = "aes-#{aes_size}-cbc" @alg = alg @digest = OpenSSL::Digest.new("sha#{@sha_size}") end |
Instance Attribute Details
#alg ⇒ Object (readonly)
The JWA algorithm used to encrypt the content master key.
14 15 16 |
# File 'lib/sandal/enc/acbc_hs.rb', line 14 def alg @alg end |
#name ⇒ Object (readonly)
The JWA name of the encryption method.
11 12 13 |
# File 'lib/sandal/enc/acbc_hs.rb', line 11 def name @name end |
Instance Method Details
#decrypt(token) ⇒ String
Decrypts an encrypted JSON Web Token.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/sandal/enc/acbc_hs.rb', line 60 def decrypt(token) parts, decoded_parts = Sandal::Enc.token_parts(token) header, encrypted_key, iv, ciphertext, auth_tag = *decoded_parts key = @alg.decrypt_key(encrypted_key) mac_key, enc_key = derive_keys(key) auth_data = parts[0] auth_data_length = [auth_data.length * 8].pack("Q>") mac_input = [auth_data, iv, ciphertext, auth_data_length].join mac = OpenSSL::HMAC.digest(@digest, mac_key, mac_input) unless auth_tag == mac[0...(mac.length / 2)] raise Sandal::InvalidTokenError, "Invalid authentication tag." end cipher = OpenSSL::Cipher.new(@cipher_name).decrypt begin cipher.key = enc_key cipher.iv = decoded_parts[2] cipher.update(decoded_parts[3]) + cipher.final rescue OpenSSL::Cipher::CipherError => e raise Sandal::InvalidTokenError, "Cannot decrypt token: #{e.}" end end |
#encrypt(header, payload) ⇒ String
Encrypts a token payload.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/sandal/enc/acbc_hs.rb', line 36 def encrypt(header, payload) key = get_encryption_key mac_key, enc_key = derive_keys(key) encrypted_key = @alg.encrypt_key(key) cipher = OpenSSL::Cipher.new(@cipher_name).encrypt cipher.key = enc_key cipher.iv = iv = SecureRandom.random_bytes(16) ciphertext = cipher.update(payload) + cipher.final auth_data = Sandal::Util.jwt_base64_encode(header) auth_data_length = [auth_data.length * 8].pack("Q>") mac_input = [auth_data, iv, ciphertext, auth_data_length].join mac = OpenSSL::HMAC.digest(@digest, mac_key, mac_input) auth_tag = mac[0...(mac.length / 2)] remainder = [encrypted_key, iv, ciphertext, auth_tag].map { |part| Sandal::Util.jwt_base64_encode(part) } [auth_data, *remainder].join(".") end |