@@ -22,37 +22,31 @@ class InvalidData < RuntimeError; end
22
22
23
23
class << self
24
24
def encrypt ( payload , key , alg : 'RSA-OAEP' , enc : 'A128GCM' , **more_headers )
25
- header = { alg : alg , enc : enc } . merge ( more_headers )
26
- header . delete ( :zip ) if header [ :zip ] == ''
25
+ header = generate_header ( alg , enc , more_headers )
27
26
check_params ( header , key )
28
27
29
- cipher = Enc . for ( enc ) . new
30
- cipher . cek = key if alg == 'dir'
28
+ payload = apply_zip ( header , payload , :compress )
31
29
32
- payload = Zip . for ( header [ :zip ] ) . new . compress ( payload ) if header [ :zip ]
30
+ cipher = Enc . for ( enc )
31
+ cipher . cek = key if alg == 'dir'
33
32
34
- ciphertext = cipher . encrypt ( payload , Base64 . jwe_encode ( header . to_json ) )
35
- encrypted_cek = Alg . for ( alg ) . new ( key ) . encrypt ( cipher . cek )
33
+ json_hdr = header . to_json
34
+ ciphertext = cipher . encrypt ( payload , Base64 . jwe_encode ( json_hdr ) )
36
35
37
- Serialization :: Compact . encode ( header . to_json , encrypted_cek , cipher . iv , ciphertext , cipher . tag )
36
+ generate_serialization ( json_hdr , Alg . encrypt_cek ( alg , key , cipher . cek ) , ciphertext , cipher )
38
37
end
39
38
40
39
def decrypt ( payload , key )
41
40
header , enc_key , iv , ciphertext , tag = Serialization ::Compact . decode ( payload )
42
41
header = JSON . parse ( header )
43
42
check_params ( header , key )
44
43
45
- cek = Alg . for ( header [ 'alg' ] ) . new ( key ) . decrypt ( enc_key )
46
- cipher = Enc . for ( header [ 'enc' ] ) . new ( cek , iv )
47
- cipher . tag = tag
44
+ cek = Alg . decrypt_cek ( header [ 'alg' ] , key , enc_key )
45
+ cipher = Enc . for ( header [ 'enc' ] , cek , iv , tag )
48
46
49
47
plaintext = cipher . decrypt ( ciphertext , payload . split ( '.' ) . first )
50
48
51
- if header [ 'zip' ]
52
- Zip . for ( header [ 'zip' ] ) . new . decompress ( plaintext )
53
- else
54
- plaintext
55
- end
49
+ apply_zip ( header , plaintext , :decompress )
56
50
end
57
51
58
52
def check_params ( header , key )
@@ -82,5 +76,23 @@ def param_to_class_name(param)
82
76
klass = param . gsub ( /[-\+ ]/ , '_' ) . downcase . sub ( /^[a-z\d ]*/ ) { $&. capitalize }
83
77
klass . gsub ( /_([a-z\d ]*)/i ) { Regexp . last_match ( 1 ) . capitalize }
84
78
end
79
+
80
+ def apply_zip ( header , data , direction )
81
+ if header [ :zip ] || header [ 'zip' ]
82
+ Zip . for ( header [ :zip ] || header [ 'zip' ] ) . new . send ( direction , data )
83
+ else
84
+ data
85
+ end
86
+ end
87
+
88
+ def generate_header ( alg , enc , more )
89
+ header = { alg : alg , enc : enc } . merge ( more )
90
+ header . delete ( :zip ) if header [ :zip ] == ''
91
+ header
92
+ end
93
+
94
+ def generate_serialization ( hdr , cek , content , cipher )
95
+ Serialization ::Compact . encode ( hdr , cek , cipher . iv , content , cipher . tag )
96
+ end
85
97
end
86
98
end
0 commit comments