jwa 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +15 -0
  3. data/.gitignore +17 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +16 -0
  6. data/.travis.yml +15 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.md +23 -0
  9. data/README.md +26 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/jwa.gemspec +27 -0
  14. data/lib/jwa.rb +16 -0
  15. data/lib/jwa/algorithms.rb +2 -0
  16. data/lib/jwa/algorithms/content_encryption.rb +29 -0
  17. data/lib/jwa/algorithms/content_encryption/a128_cbc_hs256.rb +29 -0
  18. data/lib/jwa/algorithms/content_encryption/a128_gcm.rb +25 -0
  19. data/lib/jwa/algorithms/content_encryption/a192_cbc_hs384.rb +29 -0
  20. data/lib/jwa/algorithms/content_encryption/a192_gcm.rb +25 -0
  21. data/lib/jwa/algorithms/content_encryption/a256_cbc_hs512.rb +29 -0
  22. data/lib/jwa/algorithms/content_encryption/a256_gcm.rb +25 -0
  23. data/lib/jwa/algorithms/content_encryption/aes_cbc_hs.rb +85 -0
  24. data/lib/jwa/algorithms/content_encryption/aes_gcm.rb +64 -0
  25. data/lib/jwa/algorithms/key_management.rb +56 -0
  26. data/lib/jwa/algorithms/key_management/a128_gcm_kw.rb +21 -0
  27. data/lib/jwa/algorithms/key_management/a128_kw.rb +21 -0
  28. data/lib/jwa/algorithms/key_management/a192_gcm_kw.rb +21 -0
  29. data/lib/jwa/algorithms/key_management/a192_kw.rb +21 -0
  30. data/lib/jwa/algorithms/key_management/a256_gcm_kw.rb +21 -0
  31. data/lib/jwa/algorithms/key_management/a256_kw.rb +21 -0
  32. data/lib/jwa/algorithms/key_management/aes_gcm_kw.rb +26 -0
  33. data/lib/jwa/algorithms/key_management/aes_kw.rb +100 -0
  34. data/lib/jwa/algorithms/key_management/ecdh_es.rb +45 -0
  35. data/lib/jwa/algorithms/key_management/ecdh_es_a128_kw.rb +25 -0
  36. data/lib/jwa/algorithms/key_management/ecdh_es_a192_kw.rb +25 -0
  37. data/lib/jwa/algorithms/key_management/ecdh_es_a256_kw.rb +25 -0
  38. data/lib/jwa/algorithms/key_management/ecdh_es_kw.rb +23 -0
  39. data/lib/jwa/algorithms/key_management/pbes2.rb +27 -0
  40. data/lib/jwa/algorithms/key_management/pbes_hs256_a128_kw.rb +25 -0
  41. data/lib/jwa/algorithms/key_management/pbes_hs384_a192_kw.rb +25 -0
  42. data/lib/jwa/algorithms/key_management/pbes_hs512_a256_kw.rb +25 -0
  43. data/lib/jwa/algorithms/key_management/rsa15.rb +20 -0
  44. data/lib/jwa/algorithms/key_management/rsa_oaep.rb +20 -0
  45. data/lib/jwa/cipher.rb +17 -0
  46. data/lib/jwa/support/concat_kdf.rb +29 -0
  47. data/lib/jwa/support/pbkdf2.rb +48 -0
  48. data/lib/jwa/version.rb +3 -0
  49. data/spec/jwa/algorithms/content_encryption/a128_cbc_hs256_spec.rb +30 -0
  50. data/spec/jwa/algorithms/content_encryption/a128_gcm_spec.rb +42 -0
  51. data/spec/jwa/algorithms/content_encryption/a192_cbc_hs384_spec.rb +34 -0
  52. data/spec/jwa/algorithms/content_encryption/a192_gcm_spec.rb +49 -0
  53. data/spec/jwa/algorithms/content_encryption/a256_cbc_hs512_spec.rb +35 -0
  54. data/spec/jwa/algorithms/content_encryption/a256_gcm_spec.rb +61 -0
  55. data/spec/jwa/algorithms/content_encryption/aes_cbc_hs_shared.rb +96 -0
  56. data/spec/jwa/algorithms/content_encryption/aes_gcm_shared.rb +60 -0
  57. data/spec/jwa/algorithms/content_encryption_spec.rb +7 -0
  58. data/spec/jwa/algorithms/key_management/a128_kw_spec.rb +43 -0
  59. data/spec/jwa/algorithms/key_management/a192_kw_spec.rb +29 -0
  60. data/spec/jwa/algorithms/key_management/a256_kw_spec.rb +29 -0
  61. data/spec/jwa/algorithms/key_management/ecdh_es_spec.rb +36 -0
  62. data/spec/jwa/algorithms/key_management/pbes2_hs256_a128_kw_spec.rb +27 -0
  63. data/spec/jwa/algorithms/key_management/pbes2_hs384_a192_kw_spec.rb +32 -0
  64. data/spec/jwa/algorithms/key_management/pbes2_hs512_a256_kw_spec.rb +32 -0
  65. data/spec/jwa/algorithms/key_management/rsa15_spec.rb +44 -0
  66. data/spec/jwa/algorithms/key_management/rsa_oaep_spec.rb +44 -0
  67. data/spec/jwa/algorithms/key_management_spec.rb +7 -0
  68. data/spec/jwa/cipher_spec.rb +7 -0
  69. data/spec/jwa/support/concat_kdf_spec.rb +32 -0
  70. data/spec/jwa/support/pbkdf2_spec.rb +111 -0
  71. data/spec/jwa_spec.rb +5 -0
  72. data/spec/spec_helper.rb +22 -0
  73. data/spec/support/ec1.json +7 -0
  74. data/spec/support/ec2.json +7 -0
  75. data/spec/support/hex_helpers.rb +9 -0
  76. data/spec/support/oct16.json +4 -0
  77. data/spec/support/oct24.json +4 -0
  78. data/spec/support/oct32.json +4 -0
  79. data/spec/support/rsa1.json +11 -0
  80. data/spec/support/rsa2.json +11 -0
  81. metadata +193 -0
@@ -0,0 +1,35 @@
1
+ require_relative './aes_cbc_hs_shared'
2
+
3
+ describe JWA::Algorithms::ContentEncryption::A256CbcHs512 do
4
+ include_examples 'AES-CBC-HS' do
5
+ let(:key) do
6
+ '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
7
+ 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
8
+ 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
9
+ 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f'
10
+ end
11
+
12
+ let(:ciphertext) do
13
+ '4a ff aa ad b7 8c 31 c5 da 4b 1b 59 0d 10 ff bd
14
+ 3d d8 d5 d3 02 42 35 26 91 2d a0 37 ec bc c7 bd
15
+ 82 2c 30 1d d6 7c 37 3b cc b5 84 ad 3e 92 79 c2
16
+ e6 d1 2a 13 74 b7 7f 07 75 53 df 82 94 10 44 6b
17
+ 36 eb d9 70 66 29 6a e6 42 7e a7 5c 2e 08 46 a1
18
+ 1a 09 cc f5 37 0d c8 0b fe cb ad 28 c7 3f 09 b3
19
+ a3 b7 5e 66 2a 25 94 41 0a e4 96 b2 e2 e6 60 9e
20
+ 31 e6 e0 2c c8 37 f0 53 d2 1f 37 ff 4f 51 95 0b
21
+ be 26 38 d0 9d d7 a4 93 09 30 80 6d 07 03 b1 f6'
22
+ end
23
+
24
+ let(:tag) do
25
+ '4d d3 b4 c0 88 a7 f4 5c 21 68 39 64 5b 20 12 bf
26
+ 2e 62 69 a8 c5 6a 81 6d bc 1b 26 77 61 95 5b c5'
27
+ end
28
+ end
29
+
30
+ describe '.enc_name' do
31
+ it 'equals A256CBC-HS512' do
32
+ expect(described_class.enc_name).to eq 'A256CBC-HS512'
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,61 @@
1
+ require_relative './aes_gcm_shared'
2
+
3
+ # Test vector from JWE spec
4
+ describe JWA::Algorithms::ContentEncryption::A256Gcm do
5
+ include_examples 'AES-GCM' do
6
+ let(:plaintext) do
7
+ int_byte_array_to_bytes(
8
+ [84, 104, 101, 32, 116, 114, 117, 101, 32, 115, 105, 103, 110, 32,
9
+ 111, 102, 32, 105, 110, 116, 101, 108, 108, 105, 103, 101, 110, 99,
10
+ 101, 32, 105, 115, 32, 110, 111, 116, 32, 107, 110, 111, 119, 108,
11
+ 101, 100, 103, 101, 32, 98, 117, 116, 32, 105, 109, 97, 103, 105,
12
+ 110, 97, 116, 105, 111, 110, 46]
13
+ )
14
+ end
15
+
16
+ let(:authenticated_data) do
17
+ int_byte_array_to_bytes(
18
+ [101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69,
19
+ 116, 84, 48, 70, 70, 85, 67, 73, 115, 73, 109, 86, 117, 89, 121, 73,
20
+ 54, 73, 107, 69, 121, 78, 84, 90, 72, 81, 48, 48, 105, 102, 81]
21
+ )
22
+ end
23
+
24
+ let(:key) do
25
+ int_byte_array_to_bytes(
26
+ [177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154,
27
+ 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122,
28
+ 234, 64, 252]
29
+ )
30
+ end
31
+
32
+ let(:iv) do
33
+ int_byte_array_to_bytes(
34
+ [227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]
35
+ )
36
+ end
37
+
38
+ let(:ciphertext) do
39
+ int_byte_array_to_bytes(
40
+ [229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122,
41
+ 233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111,
42
+ 104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32,
43
+ 123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205,
44
+ 160, 109, 64, 63, 192]
45
+ )
46
+ end
47
+
48
+ let(:tag) do
49
+ int_byte_array_to_bytes(
50
+ [92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91,
51
+ 210, 145]
52
+ )
53
+ end
54
+ end
55
+
56
+ describe '.enc_name' do
57
+ it 'equals A256GCM' do
58
+ expect(described_class.enc_name).to eq 'A256GCM'
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,96 @@
1
+ shared_examples 'AES-CBC-HS' do
2
+ let(:plaintext) do
3
+ '41 20 63 69 70 68 65 72 20 73 79 73 74 65 6d 20
4
+ 6d 75 73 74 20 6e 6f 74 20 62 65 20 72 65 71 75
5
+ 69 72 65 64 20 74 6f 20 62 65 20 73 65 63 72 65
6
+ 74 2c 20 61 6e 64 20 69 74 20 6d 75 73 74 20 62
7
+ 65 20 61 62 6c 65 20 74 6f 20 66 61 6c 6c 20 69
8
+ 6e 74 6f 20 74 68 65 20 68 61 6e 64 73 20 6f 66
9
+ 20 74 68 65 20 65 6e 65 6d 79 20 77 69 74 68 6f
10
+ 75 74 20 69 6e 63 6f 6e 76 65 6e 69 65 6e 63 65'
11
+ end
12
+
13
+ let(:authenticated_data) do
14
+ '54 68 65 20 73 65 63 6f 6e 64 20 70 72 69 6e 63
15
+ 69 70 6c 65 20 6f 66 20 41 75 67 75 73 74 65 20
16
+ 4b 65 72 63 6b 68 6f 66 66 73'
17
+ end
18
+
19
+ let(:iv) { '1a f3 8c 2d c2 b9 6f fd d8 66 94 09 23 41 bc 04' }
20
+
21
+ let(:b_plaintext) { hex_string_to_bytes(plaintext) }
22
+ let(:b_authenticated_data) { hex_string_to_bytes(authenticated_data) }
23
+ let(:b_key) { hex_string_to_bytes(key) }
24
+ let(:b_iv) { hex_string_to_bytes(iv) }
25
+ let(:b_ciphertext) { hex_string_to_bytes(ciphertext) }
26
+ let(:b_tag) { hex_string_to_bytes(tag) }
27
+
28
+ subject { described_class.new(b_key, b_iv) }
29
+
30
+ it 'encrypts according to RFC7518' do
31
+ ciphertext, tag = subject.encrypt(b_plaintext, b_authenticated_data)
32
+
33
+ expect(ciphertext).to eq(b_ciphertext)
34
+ expect(tag).to eq(b_tag)
35
+ end
36
+
37
+ it 'decrypt according to RFC7518' do
38
+ plaintext = subject.decrypt(b_ciphertext, b_authenticated_data, b_tag)
39
+
40
+ expect(plaintext).to eq(b_plaintext)
41
+ end
42
+
43
+ it 'raises when provided a wrong key size' do
44
+ expect do
45
+ described_class.new(b_key + "\x00", b_iv)
46
+ end.to raise_error(ArgumentError)
47
+ end
48
+
49
+ it 'raises when provided a wrong iv size' do
50
+ expect do
51
+ described_class.new(b_key, b_iv + "\x00")
52
+ end.to raise_error(ArgumentError)
53
+ end
54
+
55
+ it 'exposes the used key' do
56
+ expect(subject.key).to eq b_key
57
+ end
58
+
59
+ it 'exposes the used iv' do
60
+ ins = described_class.new(b_key)
61
+ expect(ins.iv).to_not be_nil
62
+ end
63
+
64
+ describe '#available?' do
65
+ context 'when the cipher is not available' do
66
+ it 'is false' do
67
+ allow(JWA::Cipher).to receive(:for) { raise NotImplementedError }
68
+ expect(described_class.available?).to be_falsey
69
+ end
70
+ end
71
+
72
+ context 'when the cipher is available' do
73
+ it 'is true' do
74
+ allow(JWA::Cipher).to receive(:for)
75
+ expect(described_class.available?).to be_truthy
76
+ end
77
+ end
78
+ end
79
+
80
+ it 'raises an error if the tag is corrupt' do
81
+ expect do
82
+ subject.decrypt(b_ciphertext, b_authenticated_data, 'random data')
83
+ end.to raise_error(JWA::BadDecrypt)
84
+ end
85
+
86
+ it 'raises an error if the signature pass, but decryption fails' do
87
+ # The second half of the key influcences only decryption, but not signature checking
88
+ key = b_key.dup
89
+ key[-1] = "\x00"
90
+
91
+ ins = described_class.new(key, b_iv)
92
+ expect do
93
+ ins.decrypt(b_ciphertext, b_authenticated_data, b_tag)
94
+ end.to raise_error(JWA::BadDecrypt)
95
+ end
96
+ end
@@ -0,0 +1,60 @@
1
+ shared_examples 'AES-GCM' do
2
+ subject { described_class.new(key, iv) }
3
+
4
+ it 'encrypts according to the Test Case' do
5
+ r_ciphertext, r_tag = subject.encrypt(plaintext, authenticated_data)
6
+
7
+ expect(r_ciphertext).to eq(ciphertext)
8
+ expect(r_tag).to eq(tag)
9
+ end
10
+
11
+ it 'decrypt according to the Test Case' do
12
+ r_plaintext = subject.decrypt(ciphertext, authenticated_data, tag)
13
+
14
+ expect(r_plaintext).to eq(plaintext)
15
+ end
16
+
17
+ it 'raises when provided a wrong key size' do
18
+ expect do
19
+ described_class.new(key + "\x00", iv)
20
+ end.to raise_error(ArgumentError)
21
+ end
22
+
23
+ it 'raises when provided a wrong iv size' do
24
+ expect do
25
+ described_class.new(key, iv + "\x00")
26
+ end.to raise_error(ArgumentError)
27
+ end
28
+
29
+ it 'exposes the used key' do
30
+ expect(subject.key).to eq key
31
+ end
32
+
33
+ it 'exposes the used iv' do
34
+ ins = described_class.new(key)
35
+ expect(ins.iv).to_not be_nil
36
+ end
37
+
38
+ describe '#available?' do
39
+ context 'when the cipher is not available' do
40
+ it 'is false' do
41
+ allow(JWA::Cipher).to receive(:for) { raise NotImplementedError }
42
+ expect(described_class.available?).to be_falsey
43
+ end
44
+ end
45
+
46
+ context 'when the cipher is available' do
47
+ it 'is true' do
48
+ allow(JWA::Cipher).to receive(:for)
49
+ expect(described_class.available?).to be_truthy
50
+ end
51
+ end
52
+ end
53
+
54
+ it 'raises an error if decryption fails' do
55
+ ins = described_class.new("\x00" * described_class.key_length, iv)
56
+ expect do
57
+ ins.decrypt(ciphertext, authenticated_data, tag)
58
+ end.to raise_error(JWA::BadDecrypt)
59
+ end
60
+ end
@@ -0,0 +1,7 @@
1
+ describe JWA::Algorithms::ContentEncryption do
2
+ describe '.for' do
3
+ it 'returns a class for a given encryption method name' do
4
+ expect(described_class.for('A128GCM')).to be JWA::Algorithms::ContentEncryption::A128Gcm
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ describe JWA::Algorithms::KeyManagement::A128Kw do
2
+ let(:jwk) { JWK::Key.from_json(File.read('spec/support/oct16.json')) }
3
+
4
+ let(:plaintext) do
5
+ int_byte_array_to_bytes([4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
6
+ 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156,
7
+ 44, 207])
8
+ end
9
+
10
+ let(:ciphertext) do
11
+ int_byte_array_to_bytes([232, 160, 123, 211, 183, 76, 245, 132, 200, 128, 123, 75, 190, 216,
12
+ 22, 67, 201, 138, 193, 186, 9, 91, 122, 31, 246, 90, 28, 139, 57, 3,
13
+ 76, 124, 193, 11, 98, 37, 173, 61, 104, 57])
14
+ end
15
+
16
+ it 'decrypts according to the Test Case (RFC 7516 - Section A.3)' do
17
+ key = jwk.to_s
18
+
19
+ alg = described_class.new(key)
20
+ expect(alg.decrypt(ciphertext)).to eq plaintext
21
+ end
22
+
23
+ it 'encrypts according to the Test Case' do
24
+ key = jwk.to_s
25
+
26
+ alg = described_class.new(key)
27
+ expect(alg.encrypt(plaintext)).to eq ciphertext
28
+ end
29
+
30
+ it 'raises when the iv doesn\'t match' do
31
+ key = jwk.to_s
32
+
33
+ alg = described_class.new(key)
34
+ ciph = alg.encrypt(plaintext)
35
+
36
+ alg2 = described_class.new(key, "\xA5\xA5\xA5\xA5\xA5\xA5\xA5\xA5")
37
+ expect { alg2.decrypt(ciph) }.to raise_error(StandardError)
38
+ end
39
+
40
+ it 'raises for wrong key sizes' do
41
+ expect { described_class.new("\x00" * 12) }.to raise_error(ArgumentError)
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ describe JWA::Algorithms::KeyManagement::A192Kw do
2
+ let(:jwk) { JWK::Key.from_json(File.read('spec/support/oct24.json')) }
3
+
4
+ let(:plaintext) do
5
+ int_byte_array_to_bytes([4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
6
+ 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156,
7
+ 44, 207])
8
+ end
9
+
10
+ let(:ciphertext) do
11
+ int_byte_array_to_bytes([143, 218, 154, 233, 170, 149, 194, 128, 166, 3, 246, 159, 78, 90, 167,
12
+ 0, 22, 179, 29, 231, 11, 77, 104, 42, 102, 115, 158, 61, 247, 117,
13
+ 234, 19, 241, 102, 103, 177, 218, 215, 160, 151])
14
+ end
15
+
16
+ it 'decrypts according to the Test Case (RFC 7516 - Section A.3)' do
17
+ key = jwk.to_s
18
+
19
+ alg = described_class.new(key)
20
+ expect(alg.decrypt(ciphertext)).to eq plaintext
21
+ end
22
+
23
+ it 'encrypts according to the Test Case' do
24
+ key = jwk.to_s
25
+
26
+ alg = described_class.new(key)
27
+ expect(alg.encrypt(plaintext)).to eq ciphertext
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ describe JWA::Algorithms::KeyManagement::A256Kw do
2
+ let(:jwk) { JWK::Key.from_json(File.read('spec/support/oct32.json')) }
3
+
4
+ let(:plaintext) do
5
+ int_byte_array_to_bytes([4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106,
6
+ 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156,
7
+ 44, 207])
8
+ end
9
+
10
+ let(:ciphertext) do
11
+ int_byte_array_to_bytes([198, 158, 179, 0, 33, 254, 44, 72, 227, 132, 72, 122, 1, 139, 110, 8,
12
+ 55, 39, 196, 203, 65, 90, 255, 20, 27, 211, 159, 146, 66, 122, 239, 238,
13
+ 145, 174, 248, 60, 215, 107, 251, 14])
14
+ end
15
+
16
+ it 'decrypts according to the Test Case (RFC 7516 - Section A.3)' do
17
+ key = jwk.to_s
18
+
19
+ alg = described_class.new(key)
20
+ expect(alg.decrypt(ciphertext)).to eq plaintext
21
+ end
22
+
23
+ it 'encrypts according to the Test Case' do
24
+ key = jwk.to_s
25
+
26
+ alg = described_class.new(key)
27
+ expect(alg.encrypt(plaintext)).to eq ciphertext
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ describe JWA::Algorithms::KeyManagement::EcdhEs do
2
+ let(:alice) { JWK::Key.from_json(File.read('spec/support/ec1.json')) }
3
+ let(:bob) { JWK::Key.from_json(File.read('spec/support/ec2.json')) }
4
+
5
+ let(:expected) do
6
+ int_byte_array_to_bytes([86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26])
7
+ end
8
+
9
+ it 'resolves alice\'s key according to the spec' do
10
+ alg = described_class.new(alice.to_openssl_key, JWA::Algorithms::ContentEncryption::A128Gcm, 'Alice', 'Bob')
11
+
12
+ begin
13
+ actual = alg.encrypt(bob.to_openssl_key.public_key)
14
+ expect(actual).to eq expected
15
+ rescue Exception => e
16
+ raise e unless defined?(JRUBY_VERSION)
17
+
18
+ $stderr.puts('WARNING: This test fails on jRuby due to incorrect EC Keys implementation. It would still work ' \
19
+ 'if the OpenSSL keys were generated instead of loaded.')
20
+ end
21
+ end
22
+
23
+ it 'resolves bob\'s key according to the spec' do
24
+ alg = described_class.new(bob.to_openssl_key, JWA::Algorithms::ContentEncryption::A128Gcm, 'Alice', 'Bob')
25
+
26
+ begin
27
+ actual = alg.encrypt(alice.to_openssl_key.public_key)
28
+ expect(actual).to eq expected
29
+ rescue Exception => e
30
+ raise e unless defined?(JRUBY_VERSION)
31
+
32
+ $stderr.puts('WARNING: This test fails on jRuby due to incorrect EC Keys implementation. It would still work ' \
33
+ 'if the OpenSSL keys were generated instead of loaded.')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ describe JWA::Algorithms::KeyManagement::Pbes2Hs256A128Kw do
2
+ let(:password) { 'Thus from my lips, by yours, my sin is purged.' }
3
+ let(:salt) { int_byte_array_to_bytes([217, 96, 147, 112, 150, 117, 70, 247, 127, 8, 155, 137, 174, 42, 80, 215]) }
4
+ let(:iterations) { 4096 }
5
+
6
+ let(:plaintext) do
7
+ int_byte_array_to_bytes([111, 27, 25, 52, 66, 29, 20, 78, 92, 176, 56, 240, 65, 208, 82, 112,
8
+ 161, 131, 36, 55, 202, 236, 185, 172, 129, 23, 153, 194, 195, 48,
9
+ 253, 182])
10
+ end
11
+
12
+ let(:ciphertext) do
13
+ int_byte_array_to_bytes([78, 186, 151, 59, 11, 141, 81, 240, 213, 245, 83, 211, 53, 188, 134,
14
+ 188, 66, 125, 36, 200, 222, 124, 5, 103, 249, 52, 117, 184, 140, 81,
15
+ 246, 158, 161, 177, 20, 33, 245, 57, 59, 4])
16
+ end
17
+
18
+ it 'decrypts according to the Test Case (RFC 7517 - Appendix C)' do
19
+ alg = described_class.new(password, salt, iterations)
20
+ expect(alg.decrypt(ciphertext)).to eq plaintext
21
+ end
22
+
23
+ it 'encrypts according to the Test Case' do
24
+ alg = described_class.new(password, salt, iterations)
25
+ expect(alg.encrypt(plaintext)).to eq ciphertext
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ # WARNING:
2
+ # No public test case was found, so this was artificially generated.
3
+ # The ciphertext here is what I expect it to be, not what is known to be correct.
4
+ # Hopefully it's still correct
5
+
6
+ describe JWA::Algorithms::KeyManagement::Pbes2Hs384A192Kw do
7
+ let(:password) { 'Thus from my lips, by yours, my sin is purged.' }
8
+ let(:salt) { int_byte_array_to_bytes([217, 96, 147, 112, 150, 117, 70, 247, 127, 8, 155, 137, 174, 42, 80, 215]) }
9
+ let(:iterations) { 4096 }
10
+
11
+ let(:plaintext) do
12
+ int_byte_array_to_bytes([111, 27, 25, 52, 66, 29, 20, 78, 92, 176, 56, 240, 65, 208, 82, 112,
13
+ 161, 131, 36, 55, 202, 236, 185, 172, 129, 23, 153, 194, 195, 48,
14
+ 253, 182])
15
+ end
16
+
17
+ let(:ciphertext) do
18
+ int_byte_array_to_bytes([215, 56, 252, 107, 109, 188, 15, 220, 217, 9, 142, 195, 65, 53, 139,
19
+ 56, 180, 25, 68, 130, 147, 127, 238, 100, 239, 217, 250, 240, 70, 8,
20
+ 35, 18, 242, 142, 239, 238, 250, 130, 221, 180])
21
+ end
22
+
23
+ it 'decrypts predictably' do
24
+ alg = described_class.new(password, salt, iterations)
25
+ expect(alg.decrypt(ciphertext)).to eq plaintext
26
+ end
27
+
28
+ it 'encrypts predictably' do
29
+ alg = described_class.new(password, salt, iterations)
30
+ expect(alg.encrypt(plaintext)).to eq ciphertext
31
+ end
32
+ end