Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.54 KB | None | 0 0
  1. import base64
  2. import struct
  3. import nacl.secret
  4. import nacl.utils
  5. import nacl.hashlib
  6. import nacl.hash
  7.  
  8. BUFFER_SIZE = 4 * (1024 * 1024)
  9.  
  10. def read_file_blocks(file, extra_bytes=0):
  11. while True:
  12. data = file.read(BUFFER_SIZE + extra_bytes)
  13. if not data:
  14. break
  15. yield data
  16.  
  17. def hmac_file(file, key):
  18. blake = nacl.hashlib.blake2b(key=key)
  19. with open(file, 'rb') as in_file:
  20. for block in read_file_blocks(in_file):
  21. blake.update(block)
  22. return blake.hexdigest()
  23.  
  24. def encrypt_archive(archive_name, encrypted_name):
  25. key = nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE)
  26. #Use 4 bytes less than the nonce size to make room for the block counter
  27. nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE - 4)
  28. block_num = 0
  29.  
  30. box = nacl.secret.SecretBox(key)
  31. with open(archive_name, 'rb') as in_file, open(encrypted_name, 'wb') as out_file:
  32. for data in read_file_blocks(in_file):
  33. #Append the block counter to the nonce, so each block has a unique nonce
  34. block_nonce = nonce + struct.pack(">I", block_num)
  35. block = box.encrypt(data, block_nonce)
  36. out_file.write(block.ciphertext)
  37. block_num += 1
  38.  
  39. hmac_key = nacl.hash.sha256(key + nonce, encoder=nacl.encoding.RawEncoder)
  40. output = {}
  41. output['key'] = base64.b64encode(key + nonce)
  42. output['signature'] = hmac_file(encrypted_name, hmac_key)
  43. return output
  44.  
  45. def decrypt_archive(encrypted_name, archive_name, key_info):
  46. key_bytes = base64.b64decode(key_info['key'])
  47.  
  48. key = key_bytes[:nacl.secret.SecretBox.KEY_SIZE]
  49. nonce = key_bytes[nacl.secret.SecretBox.KEY_SIZE:]
  50.  
  51. extra_bytes = nacl.secret.SecretBox.MACBYTES
  52. hmac_key = nacl.hash.sha256(key_bytes, encoder=nacl.encoding.RawEncoder)
  53. hmac = hmac_file(encrypted_name, hmac_key)
  54. if hmac != key_info['signature']:
  55. print('hmac mismatch')
  56. return
  57.  
  58. block_num = 0
  59. box = nacl.secret.SecretBox(key)
  60. with open(encrypted_name, 'rb') as in_file, open(archive_name, 'wb') as out_file:
  61. # nacl adds a MAC to each block, when reading the file in, this needs to be taken into account
  62. for data in read_file_blocks(in_file, extra_bytes=extra_bytes):
  63. block_nonce = nonce + struct.pack(">I", block_num)
  64. block = box.decrypt(data, block_nonce)
  65. out_file.write(block)
  66. block_num += 1
  67.  
  68. key_info = encrypt_archive("C:\temp\test.csv", "C:\temp\test.enc")
  69. print(key_info)
  70. decrypt_archive("C:\temp\test.enc", "C:\temp\test.enc.csv", key_info)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement