Module: JWE::Alg::AesKw

Included in:
A128Kw, A192Kw, A256Kw
Defined in:
lib/jwe/alg/aes_kw.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#ivObject

Returns the value of attribute iv.



5
6
7
# File 'lib/jwe/alg/aes_kw.rb', line 5

def iv
  @iv
end

#keyObject

Returns the value of attribute key.



4
5
6
# File 'lib/jwe/alg/aes_kw.rb', line 4

def key
  @key
end

Instance Method Details

#cipherObject



56
57
58
59
60
# File 'lib/jwe/alg/aes_kw.rb', line 56

def cipher
  @cipher ||= OpenSSL::Cipher.new(cipher_name)
rescue RuntimeError
  raise JWE::NotImplementedError.new("The version of OpenSSL linked to your Ruby does not support the cipher #{cipher_name}.")
end

#decrypt(encrypted_cek) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/jwe/alg/aes_kw.rb', line 31

def decrypt(encrypted_cek)
  c = encrypted_cek.scan(/.{8}/m)
  a = c[0]

  r = c[1..c.length]

  5.downto(0) do |j|
    r.length.downto(1) do |i|
      t = (r.length * j) + i
      a = xor(a, t)

      b = decrypt_round(a + r[i - 1])

      a = b.chars.first(8).join
      r[i - 1] = b.chars.last(8).join
    end
  end

  if a != iv
    raise StandardError.new('The encrypted key has been tampered. Do not use this key.')
  end

  r.join
end

#decrypt_round(data) ⇒ Object



69
70
71
72
73
74
# File 'lib/jwe/alg/aes_kw.rb', line 69

def decrypt_round(data)
  cipher.decrypt
  cipher.key = key
  cipher.padding = 0
  cipher.update(data) + cipher.final
end

#encrypt(cek) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/jwe/alg/aes_kw.rb', line 12

def encrypt(cek)
  a = iv
  r = cek.scan(/.{8}/m)

  6.times do |j|
    r.length.times do |i|
      b = encrypt_round(a + r[i])

      a = b.chars.first(8).join
      r[i] = b.chars.last(8).join

      t = (r.length * j) + i + 1
      a = xor(a, t)
    end
  end

  ([a] + r).join
end

#encrypt_round(data) ⇒ Object



62
63
64
65
66
67
# File 'lib/jwe/alg/aes_kw.rb', line 62

def encrypt_round(data)
  cipher.encrypt
  cipher.key = key
  cipher.padding = 0
  cipher.update(data) + cipher.final
end

#initialize(key = nil, iv = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6") ⇒ Object



7
8
9
10
# File 'lib/jwe/alg/aes_kw.rb', line 7

def initialize(key = nil, iv = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6")
  self.iv = iv.force_encoding('ASCII-8BIT')
  self.key = key.force_encoding('ASCII-8BIT')
end

#xor(data, t) ⇒ Object



76
77
78
79
80
81
# File 'lib/jwe/alg/aes_kw.rb', line 76

def xor(data, t)
  t = ([0] * (data.length - 1)) + [t]
  data = data.chars.map(&:ord)

  data.zip(t).map { |a, b| (a ^ b).chr }.join
end