Class: JOSE::JWE::ENC_AES_CBC_HMAC

Inherits:
Struct
  • Object
show all
Defined in:
lib/jose/jwe/enc_aes_cbc_hmac.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#bitsObject

Returns the value of attribute bits

Returns:

  • (Object)

    the current value of bits



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def bits
  @bits
end

#cek_lenObject

Returns the value of attribute cek_len

Returns:

  • (Object)

    the current value of cek_len



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def cek_len
  @cek_len
end

#cipher_nameObject

Returns the value of attribute cipher_name

Returns:

  • (Object)

    the current value of cipher_name



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def cipher_name
  @cipher_name
end

#enc_lenObject

Returns the value of attribute enc_len

Returns:

  • (Object)

    the current value of enc_len



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def enc_len
  @enc_len
end

#hmacObject

Returns the value of attribute hmac

Returns:

  • (Object)

    the current value of hmac



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def hmac
  @hmac
end

#iv_lenObject

Returns the value of attribute iv_len

Returns:

  • (Object)

    the current value of iv_len



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def iv_len
  @iv_len
end

#mac_lenObject

Returns the value of attribute mac_len

Returns:

  • (Object)

    the current value of mac_len



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def mac_len
  @mac_len
end

#tag_lenObject

Returns the value of attribute tag_len

Returns:

  • (Object)

    the current value of tag_len



1
2
3
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 1

def tag_len
  @tag_len
end

Class Method Details

.from_map(fields) ⇒ Object

JOSE::JWE callbacks



5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 5

def self.from_map(fields)
  case fields['enc']
  when 'A128CBC-HS256'
    return new('aes-128-cbc', 256, 32, 16, 16, 16, 16, OpenSSL::Digest::SHA256), fields.delete('enc')
  when 'A192CBC-HS384'
    return new('aes-192-cbc', 384, 48, 16, 24, 24, 24, OpenSSL::Digest::SHA384), fields.delete('enc')
  when 'A256CBC-HS512'
    return new('aes-256-cbc', 512, 64, 16, 32, 32, 32, OpenSSL::Digest::SHA512), fields.delete('enc')
  else
    raise ArgumentError, "invalid 'enc' for JWE: #{fields['enc'].inspect}"
  end
end

Instance Method Details

#algorithmObject

JOSE::JWE::ENC callbacks



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 24

def algorithm
  case cipher_name
  when 'aes-128-cbc'
    return 'A128CBC-HS256'
  when 'aes-192-cbc'
    return 'A192CBC-HS384'
  when 'aes-256-cbc'
    return 'A256CBC-HS512'
  else
    raise ArgumentError, "unhandled JOSE::JWE::ENC_AES_CBC_HMAC cipher name: #{cipher_name.inspect}"
  end
end

#block_decrypt(aad_cipher_text_cipher_tag, cek, iv) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 37

def block_decrypt(aad_cipher_text_cipher_tag, cek, iv)
  aad, cipher_text, cipher_tag = aad_cipher_text_cipher_tag
  cek_s = StringIO.new(cek)
  mac_key = cek_s.read(mac_len)
  enc_key = cek_s.read(enc_len)
  aad_len = [(aad.bytesize * 8)].pack('Q>')
  mac_data = [aad, iv, cipher_text, aad_len].pack('a*a*a*a*')
  if cipher_tag != OpenSSL::HMAC.digest(hmac.new, mac_key, mac_data)[0...tag_len]
    raise ArgumentError, "decryption error"
  else
    cipher = OpenSSL::Cipher.new(cipher_name)
    cipher.decrypt
    cipher.key = enc_key
    cipher.iv = iv
    cipher.padding = 0
    plain_text = JOSE::JWA::PKCS7.unpad(cipher.update(cipher_text) + cipher.final)
    return plain_text
  end
end

#block_encrypt(aad_plain_text, cek, iv) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 57

def block_encrypt(aad_plain_text, cek, iv)
  aad, plain_text = aad_plain_text
  cek_s = StringIO.new(cek)
  mac_key = cek_s.read(mac_len)
  enc_key = cek_s.read(enc_len)
  cipher = OpenSSL::Cipher.new(cipher_name)
  cipher.encrypt
  cipher.key = enc_key
  cipher.iv = iv
  cipher.padding = 0
  cipher_text = cipher.update(JOSE::JWA::PKCS7.pad(plain_text)) + cipher.final
  aad_len = [(aad.bytesize * 8)].pack('Q>')
  mac_data = [aad, iv, cipher_text, aad_len].pack('a*a*a*a*')
  cipher_tag = OpenSSL::HMAC.digest(hmac.new, mac_key, mac_data)[0...tag_len]
  return cipher_text, cipher_tag
end

#next_cekObject



74
75
76
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 74

def next_cek
  return SecureRandom.random_bytes(cek_len)
end

#next_ivObject



78
79
80
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 78

def next_iv
  return SecureRandom.random_bytes(iv_len)
end

#to_map(fields) ⇒ Object



18
19
20
# File 'lib/jose/jwe/enc_aes_cbc_hmac.rb', line 18

def to_map(fields)
  return fields.put('enc', algorithm)
end