3030)
3131
3232
33- def encrypt (private , public , data ):
33+ def encrypt (private , public , data , nonce = None ):
3434 """
35- Encrypt a message.
35+ Encrypt a message by using public-key encryption .
3636
3737 Arguments:
3838 - `private`: Private key of the sender.
3939 - `public`: The public key of the recipient.
4040 - `data`: Message data (bytes).
41+ - `nonce`: A predefined nonce.
4142
4243 Return a tuple of bytes containing the nonce and the encrypted
4344 data.
@@ -49,12 +50,12 @@ def encrypt(private, public, data):
4950 padding = bytes ([padding_length ] * padding_length )
5051
5152 # Assemble and encrypt the payload
52- return pk_encrypt_raw (private , public , data + padding )
53+ return pk_encrypt_raw (private , public , data + padding , nonce = nonce )
5354
5455
5556def decrypt (private , public , nonce , data ):
5657 """
57- Decrypt a message.
58+ Decrypt a message by using public-key decryption .
5859
5960 Arguments:
6061 - `private`: Private key of the sender.
@@ -81,26 +82,27 @@ def decrypt(private, public, nonce, data):
8182 return DeliveryReceipt (payload = payload )
8283
8384
84- def pk_encrypt_raw (private , public , data ):
85+ def pk_encrypt_raw (private , public , data , nonce = None ):
8586 """
86- Encrypt data.
87+ Encrypt data by using public-key encryption .
8788
8889 Arguments:
8990 - `private`: Private key of the sender.
9091 - `public`: The public key of the recipient.
91- - `image`: Data (bytes).
92+ - `data`: Data (bytes).
93+ - `nonce`: A predefined nonce.
9294
9395 Return a tuple of bytes containing the nonce and the encrypted
9496 data.
9597 """
9698 # Assemble and encrypt the payload
9799 box = libnacl .public .Box (sk = private , pk = public )
98- return box .encrypt (data , pack_nonce = False )
100+ return box .encrypt (data , nonce = nonce , pack_nonce = False )
99101
100102
101103def pk_decrypt_raw (private , public , nonce , data ):
102104 """
103- Decrypt data.
105+ Decrypt data by using public-key decryption .
104106
105107 Arguments:
106108 - `private`: Private key of the sender.
@@ -112,7 +114,45 @@ def pk_decrypt_raw(private, public, nonce, data):
112114 """
113115 # Decrypt payload
114116 box = libnacl .public .Box (sk = private , pk = public )
115- return box .decrypt (data , nonce )
117+ return box .decrypt (data , nonce = nonce )
118+
119+
120+ def sk_encrypt_raw (key , data , nonce = None ):
121+ """
122+ Encrypt data by using secret-key encryption.
123+
124+ Arguments:
125+ - `key`: The secret key.
126+ - `data`: Data (bytes).
127+ - `nonce`: A predefined nonce.
128+
129+ Return a tuple of bytes containing the nonce and the encrypted
130+ data.
131+ """
132+ # Assemble and encrypt the payload
133+ box = libnacl .secret .SecretBox (key = key )
134+ # Note: Workaround for libnacl which lacks `pack_nonce` option
135+ # (see: )
136+ #return box.encrypt(data, nonce=nonce, pack_nonce=False)
137+ data = box .encrypt (data , nonce = nonce )
138+ nonce_length = libnacl .crypto_secretbox_NONCEBYTES
139+ return data [:nonce_length ], data [nonce_length :]
140+
141+
142+ def sk_decrypt_raw (key , nonce , data ):
143+ """
144+ Decrypt data by using secret-key decryption.
145+
146+ Arguments:
147+ - `key`: The secret key.
148+ - `nonce`: The nonce of the encrypted message.
149+ - `data`: Encrypted data (bytes).
150+
151+ Return the decrypted data.
152+ """
153+ # Decrypt payload
154+ box = libnacl .secret .SecretBox (key = key )
155+ return box .decrypt (data , nonce = nonce )
116156
117157
118158class Message (metaclass = abc .ABCMeta ):
@@ -558,15 +598,17 @@ def send(self):
558598 with open (self .file_path , mode = 'rb' ) as file :
559599 self .file_content = file .read ()
560600
601+ # Create symmetric key
602+ key , hex_key = Key .generate_secret_key ()
603+
561604 # Encrypt and upload file
562- box = libnacl .secret .SecretBox ()
563- file_data = box .encrypt (self .file_content , nonce = self .nonce ['file' ])
605+ _ , file_data = sk_encrypt_raw (key , self .file_content , nonce = self .nonce ['file' ])
564606 file_id = self .connection .upload (file_data )
565607
566608 # Build JSON
567609 content = {
568610 'b' : file_id ,
569- 'k' : box . hex_sk () .decode ('utf-8' ),
611+ 'k' : hex_key .decode ('utf-8' ),
570612 'm' : self .mime_type ,
571613 'n' : os .path .basename (self .file_path ),
572614 's' : len (self .file_content ),
@@ -581,8 +623,8 @@ def send(self):
581623 self .thumbnail_content = file .read ()
582624
583625 # Encrypt and upload thumbnail
584- thumbnail_data = box . encrypt ( self .thumbnail_content ,
585- nonce = self .nonce ['thumbnail' ])
626+ _ , thumbnail_data = sk_encrypt_raw ( key , self .thumbnail_content ,
627+ nonce = self .nonce ['thumbnail' ])
586628 thumbnail_id = self .connection .upload (thumbnail_data )
587629
588630 # Update JSON
0 commit comments