1
1
# from future import standard_library
2
2
import os
3
3
4
+
4
5
try :
5
6
from builtins import object
6
7
except ImportError :
16
17
from cryptography .hazmat .primitives import hashes
17
18
from cryptography .hazmat .primitives .asymmetric import ec
18
19
from cryptography .hazmat .primitives .asymmetric import padding
20
+ from cryptography .hazmat .primitives .ciphers import algorithms
21
+ from cryptography .hazmat .primitives .ciphers import Cipher
22
+ from cryptography .hazmat .primitives .ciphers import modes
19
23
from cryptography .hazmat .primitives .ciphers .aead import AESGCM
20
- from cryptography .hazmat .primitives .ciphers .aead import AESCCM
21
24
from cryptography .hazmat .primitives .keywrap import aes_key_unwrap
22
25
from cryptography .hazmat .primitives .keywrap import aes_key_wrap
26
+ from cryptography .hazmat .primitives .padding import PKCS7
23
27
24
28
from cryptojwt import as_bytes , b64encode_item
25
29
from cryptojwt import as_unicode
@@ -156,6 +160,53 @@ def decrypt(self, ciphertext, key, sign_padding="pkcs1_padding"):
156
160
return text
157
161
158
162
163
+ class AES_CBCEncrypter (Encrypter ):
164
+ """
165
+ """
166
+ def __init__ (self , key_len = 32 , key = None , msg_padding = 'PKCS7' ):
167
+ Encrypter .__init__ (self )
168
+ if key :
169
+ self .key = key
170
+ else :
171
+ self .key = os .urandom (key_len )
172
+
173
+ if msg_padding == 'PKCS7' :
174
+ self .padder = PKCS7 (128 ).padder ()
175
+ self .unpadder = PKCS7 (128 ).unpadder ()
176
+
177
+ def encrypt (self , msg , iv = '' , auth_data = b'' ):
178
+ if not iv :
179
+ iv = os .urandom (16 )
180
+
181
+ cipher = Cipher (algorithms .AES (self .key ), modes .CBC (iv ),
182
+ backend = default_backend ())
183
+ encryptor = cipher .encryptor ()
184
+ if auth_data :
185
+ encryptor .authenticate_additional_data (auth_data )
186
+
187
+ pmsg = self .padder .update (msg )
188
+ pmsg += self .padder .finalize ()
189
+ ct = encryptor .update (pmsg )
190
+ ct += encryptor .finalize ()
191
+ return ct
192
+
193
+ def decrypt (self , msg , key = None , iv = '' , auth_data = b'' ,
194
+ padding = 'PKCS7' ):
195
+ if key is None :
196
+ key = self .key
197
+
198
+ cipher = Cipher (algorithms .AES (key ), modes .CBC (iv ),
199
+ backend = default_backend ())
200
+ decryptor = cipher .decryptor ()
201
+ if auth_data :
202
+ decryptor .authenticate_additional_data (auth_data )
203
+ ctext = decryptor .update (msg )
204
+ ctext += decryptor .finalize ()
205
+ unpad = self .unpadder .update (ctext )
206
+ unpad += self .unpadder .finalize ()
207
+ return unpad
208
+
209
+
159
210
class AES_GCMEncrypter (Encrypter ):
160
211
def __init__ (self , bit_length = 0 , key = None ):
161
212
Encrypter .__init__ (self )
@@ -167,7 +218,7 @@ def __init__(self, bit_length=0, key=None):
167
218
168
219
self .key = AESGCM .generate_key (bit_length = bit_length )
169
220
170
- def encrypt (self , msg , iv = '' , ass_data = None ):
221
+ def encrypt (self , msg , iv = '' , auth_data = None ):
171
222
"""
172
223
Encrypts and authenticates the data provided as well as authenticating
173
224
the associated_data.
@@ -180,9 +231,9 @@ def encrypt(self, msg, iv='', ass_data=None):
180
231
if not iv :
181
232
raise ValueError ('Missing Nonce' )
182
233
183
- return self .key .encrypt (iv , msg , ass_data )
234
+ return self .key .encrypt (iv , msg , auth_data )
184
235
185
- def decrypt (self , ciphertext , iv = '' , ass_data = None ):
236
+ def decrypt (self , ciphertext , iv = '' , auth_data = None ):
186
237
"""
187
238
Decrypts the data and authenticates the associated_data (if provided).
188
239
@@ -194,48 +245,48 @@ def decrypt(self, ciphertext, iv='', ass_data=None):
194
245
if not iv :
195
246
raise ValueError ('Missing Nonce' )
196
247
197
- return self .key .decrypt (iv , ciphertext , ass_data )
198
-
248
+ return self .key .decrypt (iv , ciphertext , auth_data )
199
249
200
- class AES_CCMEncrypter (Encrypter ):
201
- def __init__ (self , bit_length = 0 , key = None , tag_length = 16 ):
202
- Encrypter .__init__ (self )
203
- if key :
204
- self .key = AESCCM (key )
205
- elif bit_length :
206
- if bit_length not in [128 , 192 , 256 ]:
207
- raise UnsupportedBitLength (bit_length )
208
-
209
- self .key = AESCCM .generate_key (bit_length = bit_length )
210
250
211
- def encrypt (self , msg , iv = '' , ass_data = None ):
212
- """
213
- Encrypts and authenticates the data provided as well as authenticating
214
- the associated_data.
215
-
216
- :param msg: The message to be encrypted
217
- :param iv: MUST be present. A value of between 7 and 13 bytes.
218
- :param ass_data: Associated data
219
- :return: The ciphertext bytes with the 16 byte tag appended.
220
- """
221
- if not iv :
222
- raise ValueError ('Missing Nonce' )
223
-
224
- return self .key .encrypt (iv , msg , ass_data )
225
-
226
- def decrypt (self , ciphertext , iv = '' , ass_data = None ):
227
- """
228
- Decrypts the data and authenticates the associated_data (if provided).
229
-
230
- :param ciphertext: The data to decrypt including tag
231
- :param iv: A value of between 7 and 13 bytes.
232
- :param ass_data: Associated data
233
- :return: The original plaintext
234
- """
235
- if not iv :
236
- raise ValueError ('Missing Nonce' )
237
-
238
- return self .key .decrypt (iv , ciphertext , ass_data )
251
+ # class AES_CCMEncrypter(Encrypter):
252
+ # def __init__(self, bit_length=0, key=None, tag_length=16):
253
+ # Encrypter.__init__(self)
254
+ # if key:
255
+ # self.key = AESCCM(key)
256
+ # elif bit_length:
257
+ # if bit_length not in [128, 192, 256]:
258
+ # raise UnsupportedBitLength(bit_length)
259
+ #
260
+ # self.key = AESCCM.generate_key(bit_length=bit_length)
261
+ #
262
+ # def encrypt(self, msg, iv='', ass_data=None):
263
+ # """
264
+ # Encrypts and authenticates the data provided as well as authenticating
265
+ # the associated_data.
266
+ #
267
+ # :param msg: The message to be encrypted
268
+ # :param iv: MUST be present. A value of between 7 and 13 bytes.
269
+ # :param ass_data: Associated data
270
+ # :return: The ciphertext bytes with the 16 byte tag appended.
271
+ # """
272
+ # if not iv:
273
+ # raise ValueError('Missing Nonce')
274
+ #
275
+ # return self.key.encrypt(iv, msg, ass_data)
276
+ #
277
+ # def decrypt(self, ciphertext, iv='', ass_data=None):
278
+ # """
279
+ # Decrypts the data and authenticates the associated_data (if provided).
280
+ #
281
+ # :param ciphertext: The data to decrypt including tag
282
+ # :param iv: A value of between 7 and 13 bytes.
283
+ # :param ass_data: Associated data
284
+ # :return: The original plaintext
285
+ # """
286
+ # if not iv:
287
+ # raise ValueError('Missing Nonce')
288
+ #
289
+ # return self.key.decrypt(iv, ciphertext, ass_data)
239
290
240
291
241
292
# ---------------------------------------------------------------------------
@@ -414,9 +465,11 @@ def _generate_iv(encalg, iv=""):
414
465
return iv
415
466
else :
416
467
if encalg in ENCALGLEN1 :
417
- _iv = get_random_bytes (12 )
468
+ # _iv = get_random_bytes(ENCALGLEN1[encalg])
469
+ _iv = get_random_bytes (16 )
418
470
elif encalg in ENCALGLEN2 :
419
- _iv = get_random_bytes (12 )
471
+ # _iv = get_random_bytes(ENCALGLEN2[encalg])
472
+ _iv = get_random_bytes (16 )
420
473
else :
421
474
raise Exception ("Unsupported encryption algorithm %s" % encalg )
422
475
@@ -440,7 +493,7 @@ def _generate_key(encalg, cek=""):
440
493
def alg2keytype (self , alg ):
441
494
return alg2keytype (alg )
442
495
443
- def enc_setup (self , enc_alg , msg , auth_data , key = None , iv = "" ):
496
+ def enc_setup (self , enc_alg , msg , auth_data = b'' , key = None , iv = "" ):
444
497
""" Encrypt JWE content.
445
498
446
499
:param enc_alg: The JWE "enc" value specifying the encryption algorithm
@@ -453,17 +506,17 @@ def enc_setup(self, enc_alg, msg, auth_data, key=None, iv=""):
453
506
iv = self ._generate_iv (enc_alg , iv )
454
507
455
508
if enc_alg in ["A192GCM" , "A128GCM" , "A256GCM" ]:
456
- aes = AES_GCMEncrypter (KEYLEN [enc_alg ], key = key )
509
+ aes = AES_GCMEncrypter (ENCALGLEN1 [enc_alg ], key = key )
457
510
elif enc_alg in ["A128CBC-HS256" , "A192CBC-HS384" , "A256CBC-HS512" ]:
458
- aes = AES_CCMEncrypter ( KEYLEN [enc_alg ], key = key )
511
+ aes = AES_CBCEncrypter ( ENCALGLEN2 [enc_alg ], key = key )
459
512
else :
460
513
raise NotSupportedAlgorithm (enc_alg )
461
514
462
- ctxt , tag = split_ctx_and_tag (aes .encrypt (msg , iv , auth_data ))
463
- return ctxt , tag , aes .key
515
+ res = split_ctx_and_tag (aes .encrypt (msg , iv , auth_data ))
516
+ return res [ 0 ], res [ 1 ] , aes .key
464
517
465
518
@staticmethod
466
- def _decrypt (enc , key , ctxt , auth_data , iv , tag ):
519
+ def _decrypt (enc , key , ctxt , iv , tag , p_header = b'' , auth_data = b'' ):
467
520
""" Decrypt JWE content.
468
521
469
522
:param enc: The JWE "enc" value specifying the encryption algorithm
@@ -477,13 +530,13 @@ def _decrypt(enc, key, ctxt, auth_data, iv, tag):
477
530
if enc in ["A128GCM" , "A192GCM" , "A256GCM" ]:
478
531
aes = AES_GCMEncrypter (key = key )
479
532
elif enc in ["A128CBC-HS256" , "A192CBC-HS384" , "A256CBC-HS512" ]:
480
- aes = AES_CCMEncrypter (key = key )
533
+ aes = AES_CBCEncrypter (key = key )
481
534
else :
482
535
raise Exception ("Unsupported encryption algorithm %s" % enc )
483
536
484
537
ct = ctxt + tag
485
538
try :
486
- return aes .decrypt (ct , iv , auth_data )
539
+ return aes .decrypt (ct , iv = iv , auth_data = auth_data )
487
540
except DecryptionFailed :
488
541
raise
489
542
@@ -530,9 +583,7 @@ def encrypt(self, key, iv="", cek="", **kwargs):
530
583
531
584
_enc = self ["enc" ]
532
585
533
- ctxt , tag , cek = self .enc_setup (_enc , _msg .encode (),
534
- jwe .b64_encode_header (),
535
- cek , iv = iv )
586
+ ctxt , tag , cek = self .enc_setup (_enc , _msg .encode (), key = cek , iv = iv )
536
587
return jwe .pack (parts = [jek , iv , ctxt , tag ])
537
588
538
589
def decrypt (self , token , key = None , cek = None ):
@@ -560,8 +611,8 @@ def decrypt(self, token, key=None, cek=None):
560
611
561
612
msg = self ._decrypt (
562
613
jwe .headers ["enc" ], cek , jwe .ciphertext (),
563
- jwe .b64_protected_header (),
564
- jwe .initialization_vector (), jwe .authentication_tag ())
614
+ p_header = jwe .b64_protected_header (),
615
+ iv = jwe .initialization_vector (), tag = jwe .authentication_tag ())
565
616
566
617
if "zip" in self and self ["zip" ] == "DEF" :
567
618
msg = zlib .decompress (msg )
@@ -616,9 +667,9 @@ def encrypt(self, key, iv="", cek="", **kwargs):
616
667
617
668
jwe = JWEnc (** self .headers ())
618
669
619
- enc_header = jwe .b64_encode_header ()
670
+ # enc_header = jwe.b64_encode_header()
620
671
621
- ctxt , tag , key = self .enc_setup (_enc , _msg , enc_header , cek , iv )
672
+ ctxt , tag , key = self .enc_setup (_enc , _msg , key = cek , iv = iv )
622
673
return jwe .pack (parts = [jwe_enc_key , iv , ctxt , tag ])
623
674
624
675
def decrypt (self , token , key , cek = None ):
@@ -656,9 +707,9 @@ def decrypt(self, token, key, cek=None):
656
707
raise NotSupportedAlgorithm (enc )
657
708
658
709
msg = self ._decrypt (enc , cek , jwe .ciphertext (),
659
- jwe .b64_protected_header (),
660
- jwe .initialization_vector (),
661
- jwe .authentication_tag ())
710
+ p_header = jwe .b64_protected_header (),
711
+ iv = jwe .initialization_vector (),
712
+ tag = jwe .authentication_tag ())
662
713
663
714
if "zip" in jwe .headers and jwe .headers ["zip" ] == "DEF" :
664
715
msg = zlib .decompress (msg )
@@ -719,7 +770,7 @@ class JWE_EC(JWe):
719
770
args = JWe .args [:]
720
771
args .append ("enc" )
721
772
722
- def enc_setup (self , msg , auth_data , key = None , ** kwargs ):
773
+ def enc_setup (self , msg , key = None , auth_data = b'' , ** kwargs ):
723
774
"""
724
775
725
776
:param msg: Message to be encrypted
@@ -863,8 +914,8 @@ def encrypt(self, iv="", cek="", **kwargs):
863
914
864
915
jwe = JWEnc (** _args )
865
916
ctxt , tag , cek = super (JWE_EC , self ).enc_setup (self ["enc" ], _msg ,
866
- jwe .b64_encode_header (),
867
- cek , iv = iv )
917
+ # jwe.b64_encode_header(),
918
+ key = cek , iv = iv )
868
919
if 'encrypted_key' in kwargs :
869
920
return jwe .pack (parts = [kwargs ['encrypted_key' ], iv , ctxt , tag ])
870
921
return jwe .pack (parts = [iv , ctxt , tag ])
@@ -881,8 +932,8 @@ def decrypt(self, token=None, **kwargs):
881
932
882
933
msg = super (JWE_EC , self )._decrypt (self .headers ["enc" ], self .cek ,
883
934
self .ctxt ,
884
- jwe .b64part [0 ],
885
- self .iv , self .tag )
935
+ # p_header= jwe.b64part[0],
936
+ iv = self .iv , tag = self .tag )
886
937
self .msg = msg
887
938
self .msg_valid = True
888
939
return msg
@@ -962,7 +1013,7 @@ def encrypt(self, keys=None, cek="", iv="", **kwargs):
962
1013
963
1014
encrypter = JWE_EC (** self ._dict )
964
1015
cek , encrypted_key , iv , params , eprivk = encrypter .enc_setup (
965
- self .msg , self . _dict , key = keys [0 ], ** self ._dict )
1016
+ self .msg , key = keys [0 ], ** self ._dict )
966
1017
kwargs ["encrypted_key" ] = encrypted_key
967
1018
kwargs ["params" ] = params
968
1019
else :
0 commit comments