Module: JWE

Defined in:
lib/jwe.rb

Defined Under Namespace

Classes: DecryptionFailed, InvalidFormat, UnexpectedAlgorithm

Class Method Summary collapse

Class Method Details

.base64url_decode(str) ⇒ Object



100
101
102
103
# File 'lib/jwe.rb', line 100

def base64url_decode(str)
  str += '=' *(4 - str.length.modulo(4))
  Base64.decode64(str.tr('-_', '+/'))
end

.base64url_encode(str) ⇒ Object



105
106
107
# File 'lib/jwe.rb', line 105

def base64url_encode(str)
  Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
end

.decode_cipher_text(cipher_text, iv, private_key, cipher_name) ⇒ Object



23
24
25
26
27
# File 'lib/jwe.rb', line 23

def decode_cipher_text(cipher_text, iv, private_key, cipher_name)
  cipher_text = base64url_decode(cipher_text)
  text = decrypt(private_key, decode_iv(iv), cipher_name, cipher_text)
  decode_json base64url_decode(text)
end

.decode_iv(iv_code) ⇒ Object



49
50
51
# File 'lib/jwe.rb', line 49

def decode_iv(iv_code)
  base64url_decode(iv_code)
end

.decode_json(encoded_json) ⇒ Object



91
92
93
94
95
# File 'lib/jwe.rb', line 91

def decode_json(encoded_json)
  JSON.parse(encoded_json)
rescue JSON::ParseError
  raise JOSE::DecodeError.new("Invalid encoding")
end

.decode_key(code) ⇒ Object



34
35
36
37
# File 'lib/jwe.rb', line 34

def decode_key(code)
  code = base64url_decode(code)
  decrypt_jwe_encrypted_key(code)
end

.decode_protected_header(code) ⇒ Object



42
43
44
# File 'lib/jwe.rb', line 42

def decode_protected_header(code)
  decode_json(base64url_decode(code))
end

.decrypt(private_key, iv, cipher_name, cipher_text) ⇒ Object



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

def decrypt(private_key, iv, cipher_name, cipher_text)
  decryption = get_cipher_method(get_cipher_name(cipher_name))
  decryption.decrypt
  decryption.key = private_key
  decryption.iv = iv
  decryption.update(cipher_text) + decryption.final
end

.decrypt_jwe_encrypted_key(encrypted_key) ⇒ Object



85
86
87
88
89
# File 'lib/jwe.rb', line 85

def decrypt_jwe_encrypted_key(encrypted_key)
  encrypted_key = base64url_decode encrypted_key
  rsa = OpenSSL::PKey::RSA.new File.read 'rsa.pem'
  rsa.public_decrypt encrypted_key
end

.encode_cipher_text(cipher_text) ⇒ Object



20
21
22
# File 'lib/jwe.rb', line 20

def encode_cipher_text(cipher_text)
  base64url_encode(cipher_text)
end

.encode_header(alg) ⇒ Object



28
29
30
# File 'lib/jwe.rb', line 28

def encode_header(alg)
  alg = {'alg' => alg}
end

.encode_iv(iv) ⇒ Object



45
46
47
# File 'lib/jwe.rb', line 45

def encode_iv(iv)
  base64url_encode(iv)
end

.encode_json(raw) ⇒ Object



97
98
99
# File 'lib/jwe.rb', line 97

def encode_json(raw)
  JSON.generate(raw)
end

.encode_key(key) ⇒ Object



31
32
33
# File 'lib/jwe.rb', line 31

def encode_key(key)
  base64url_encode generate_jwe_encrypted_key(key)
end

.encode_protected_header(encrypt_method, p_header = {}) ⇒ Object



38
39
40
41
# File 'lib/jwe.rb', line 38

def encode_protected_header(encrypt_method, p_header={})
  header = {'enc' => encrypt_method}.merge(p_header)
  base64url_encode(encode_json(header))
end

.encrypt(private_key, iv, cipher_name, plain_text) ⇒ Object



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

def encrypt(private_key, iv, cipher_name, plain_text)
  encryption = get_cipher_method(get_cipher_name(cipher_name))
  encryption.encrypt
  encryption.key = private_key
  encryption.iv = iv
  encrypt_input = base64url_encode(encode_json(plain_text))
  encryption.update(encrypt_input) + encryption.final
end

.generate_cipher_text(plain_text, cipher_name, private_key) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/jwe.rb', line 11

def generate_cipher_text(plain_text, cipher_name, private_key)
  cipher = get_cipher_method(get_cipher_name(cipher_name))
  iv = cipher.random_iv
  cipher_text = encrypt(private_key, iv, cipher_name,plain_text)

  iv_encode = encode_iv(iv)
  cipher_text_encode = encode_cipher_text(cipher_text)
  [iv_encode, cipher_text_encode]
end

.generate_jwe_encrypted_key(key) ⇒ Object



77
78
79
80
81
82
83
84
# File 'lib/jwe.rb', line 77

def generate_jwe_encrypted_key(key)
  rsa = OpenSSL::PKey::RSA.new 2048
  rsa_pem = rsa.to_pem
  open('rsa.pem', 'w'){ |file|
    file.puts rsa_pem
  }
  rsa.private_encrypt key
end

.get_cipher_method(cipher_name) ⇒ Object



57
58
59
# File 'lib/jwe.rb', line 57

def get_cipher_method(cipher_name)
  OpenSSL::Cipher.new cipher_name
end

.get_cipher_name(name) ⇒ Object



53
54
55
# File 'lib/jwe.rb', line 53

def get_cipher_name(name)
  'aes-256-cbc'
end

.secure_compare(a, b) ⇒ Object



108
109
110
111
112
113
114
115
# File 'lib/jwe.rb', line 108

def secure_compare(a, b)
  return false if a.nil? || b.nil? || a.empty? || b.empty? || a.bytesize != b.bytesize
  l = a.unpack "C#{a.bytesize}"

  res = 0
  b.each_byte { |byte| res |= byte ^ l.shift }
  res == 0
end