Advertisement
Guest User

meduza.py - semisymmetric file encryption with pycryptodome

a guest
Nov 13th, 2021
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.73 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. RSA_KEY_SIZE = 2048
  4.  
  5.  
  6. import sys
  7. from getpass import getpass
  8.  
  9. from Crypto.Hash import SHA256
  10. from Crypto.Cipher import ChaCha20, PKCS1_OAEP
  11. from Crypto.PublicKey import RSA
  12. from Crypto.Random import get_random_bytes
  13.  
  14. def make_prng(seed):
  15.     key = SHA256.SHA256Hash(seed).digest()
  16.     nonce = SHA256.SHA256Hash(key).digest()[:12]
  17.     cc = ChaCha20.new(key=key, nonce=nonce)
  18.     def prng(n):
  19.         return cc.encrypt(b'0'*n)
  20.     return prng
  21.  
  22. def emit_pub_key(seed, size=2048):
  23.     prng = make_prng(seed)
  24.     key = RSA.generate(size, randfunc=prng)
  25.     return key.public_key().export_key('PEM')
  26.  
  27. def encrypt(file, pub_key):
  28.     pub_key = RSA.import_key(pub_key)
  29.     rsa = PKCS1_OAEP.new(pub_key)
  30.  
  31.     sess_key = get_random_bytes(32)
  32.     cc = ChaCha20.new(key=sess_key)
  33.     sess_key += cc.nonce
  34.  
  35.     enc_key = rsa.encrypt(sess_key)
  36.     sys.stdout.buffer.write(len(enc_key).to_bytes(4, 'little'))
  37.     sys.stdout.buffer.write(enc_key)
  38.  
  39.     f = open(file, 'rb')
  40.     while True:
  41.         b = f.read(1024**2)
  42.         if not b: break
  43.         e = cc.encrypt(b)
  44.         sys.stdout.buffer.write(e)
  45.  
  46. def decrypt(file, seed, size=2048):
  47.     f = open(file, 'rb')
  48.     key_size = int.from_bytes(f.read(4), 'little')
  49.     sess_key = f.read(key_size)
  50.  
  51.     prng = make_prng(seed)
  52.     rsa_key = RSA.generate(size, randfunc=prng)
  53.     rsa = PKCS1_OAEP.new(rsa_key)
  54.     sess_key = rsa.decrypt(sess_key)
  55.  
  56.     sess_key, nonce = sess_key[:32], sess_key[32:]
  57.     cc = ChaCha20.new(key=sess_key, nonce=nonce)
  58.  
  59.     while True:
  60.         b = f.read(1024**2)
  61.         if not b: break
  62.         d = cc.decrypt(b)
  63.         sys.stdout.buffer.write(d)
  64.  
  65. def get_seed(prompt):
  66.     pswd = getpass(prompt, stream=sys.stderr)
  67.     seed = pswd.encode()
  68.     return seed
  69.  
  70.  
  71.  
  72. if len(sys.argv) < 2:
  73.     print(f'''Usage:
  74.    {sys.argv[0]} <file> <public_key.pem>   - to encrypt a file;
  75.    {sys.argv[0]} <file>                    - to decrypt a file;
  76.    {sys.argv[0]} -k                        - to generate a public key.
  77.  
  78.    Everything goes to stdout.
  79.  
  80.    Examples:
  81.        {sys.argv[0]} -k > key.pem
  82.        {sys.argv[0]} secret.txt key.pem > secret.txt.enc
  83.  
  84.        {sys.argv[0]} secret.txt.enc > secret_dec.txt
  85.    ''')
  86.     exit(0)
  87.  
  88.  
  89. if sys.argv[1] == '-k':
  90.     seed = get_seed('Enter new passphrase: ')
  91.     print(emit_pub_key(seed, RSA_KEY_SIZE).decode())
  92.     exit(0)
  93.  
  94. if len(sys.argv) == 2:
  95.     seed = get_seed('Enter passphrase to decrypt: ')
  96.     decrypt(sys.argv[1], seed, RSA_KEY_SIZE)
  97.     exit(0)
  98.  
  99. if len(sys.argv) == 3:
  100.     pub_key = open(sys.argv[2], 'rb').read()
  101.     encrypt(sys.argv[1], pub_key)
  102.     exit(0)
  103.  
  104.  
  105. print('Wrong argument count.\nRun program without args for syntax help.', file=sys.stderr)
  106. exit(1)
  107.  
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement