diff --git a/README.md b/README.md index fad777c..cc15684 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,19 @@ plaintext = JWE.decrypt(encrypted, key) puts plaintext #"The quick brown fox jumps over the lazy dog." ``` +This example sets an extra header. + +```ruby +require 'jwe' + +keys = { + 'id-1' => OpenSSL::PKey::RSA.generate(2048) +} +payload = "The quick brown fox jumps over the lazy dog." + +encrypted = JWE.encrypt(payload, keys['id-1'], headers: {kid: 'id-1'}) +puts encrypted + ## Available Algorithms The RFC 7518 JSON Web Algorithms (JWA) spec defines the algorithms for [encryption](https://tools.ietf.org/html/rfc7518#section-5.1) diff --git a/lib/jwe.rb b/lib/jwe.rb index 2192915..286f340 100644 --- a/lib/jwe.rb +++ b/lib/jwe.rb @@ -19,7 +19,7 @@ class InvalidData < RuntimeError; end VALID_ENC = ['A128CBC-HS256', 'A192CBC-HS384', 'A256CBC-HS512', 'A128GCM', 'A192GCM', 'A256GCM'].freeze VALID_ZIP = ['DEF'].freeze - def self.encrypt(payload, key, alg: 'RSA-OAEP', enc: 'A128GCM', zip: nil) + def self.encrypt(payload, key, alg: 'RSA-OAEP', enc: 'A128GCM', zip: nil, headers: {}) raise ArgumentError.new("\"#{alg}\" is not a valid alg method") unless VALID_ALG.include?(alg) raise ArgumentError.new("\"#{enc}\" is not a valid enc method") unless VALID_ENC.include?(enc) raise ArgumentError.new("\"#{zip}\" is not a valid zip method") unless zip.nil? || zip == '' || VALID_ZIP.include?(zip) @@ -27,6 +27,7 @@ def self.encrypt(payload, key, alg: 'RSA-OAEP', enc: 'A128GCM', zip: nil) header = { alg: alg, enc: enc } header[:zip] = zip if zip && zip != '' + header.merge!(headers) if headers.is_a?(Hash) cipher = Enc.for(enc).new cipher.cek = key if alg == 'dir' diff --git a/spec/jwe_spec.rb b/spec/jwe_spec.rb index a9a8a15..b2e23e2 100644 --- a/spec/jwe_spec.rb +++ b/spec/jwe_spec.rb @@ -29,6 +29,18 @@ end end + describe 'when using extra headers' do + it 'roundtrips' do + encrypted = JWE.encrypt(plaintext, rsa_key, headers: {kid: 'some-kid-1'}) + result = JWE.decrypt(encrypted, rsa_key) + header, _ = JWE::Serialization::Compact.decode(encrypted) + header = JSON.parse(header) + + expect(header['kid']).to eq 'some-kid-1' + expect(result).to eq plaintext + end + end + it 'raises when passed a bad alg' do expect { JWE.encrypt(plaintext, rsa_key, alg: 'TEST') }.to raise_error(ArgumentError) end