|
- ##########################################################################
- #
- # pgAdmin 4 - PostgreSQL Tools
- #
- # Copyright (C) 2013 - 2020, The pgAdmin Development Team
- # This software is released under the PostgreSQL Licence
- #
- #########################################################################
-
- """This File Provides Cryptography."""
-
- from __future__ import division
-
- import base64
- import hashlib
- import os
-
- import six
-
- from cryptography.hazmat.backends import default_backend
- from cryptography.hazmat.primitives.ciphers import Cipher
- from cryptography.hazmat.primitives.ciphers.algorithms import AES
- from cryptography.hazmat.primitives.ciphers.modes import CFB8
-
- padding_string = b'}'
- iv_size = AES.block_size // 8
-
-
- def encrypt(plaintext, key):
- """
- Encrypt the plaintext with AES method.
-
- Parameters:
- plaintext -- String to be encrypted.
- key -- Key for encryption.
- """
-
- iv = os.urandom(iv_size)
- cipher = Cipher(AES(pad(key)), CFB8(iv), default_backend())
- encryptor = cipher.encryptor()
-
- # If user has entered non ascii password (Python2)
- # we have to encode it first
- if isinstance(plaintext, six.text_type):
- plaintext = plaintext.encode()
-
- return base64.b64encode(iv + encryptor.update(plaintext) +
- encryptor.finalize())
-
-
- def decrypt(ciphertext, key):
- """
- Decrypt the AES encrypted string.
-
- Parameters:
- ciphertext -- Encrypted string with AES method.
- key -- key to decrypt the encrypted string.
- """
-
- ciphertext = base64.b64decode(ciphertext)
- iv = ciphertext[:iv_size]
-
- cipher = Cipher(AES(pad(key)), CFB8(iv), default_backend())
- decryptor = cipher.decryptor()
- return decryptor.update(ciphertext[iv_size:]) + decryptor.finalize()
-
-
- def pad(key):
- """Add padding to the key."""
-
- if isinstance(key, six.text_type):
- key = key.encode()
-
- # Key must be maximum 32 bytes long, so take first 32 bytes
- key = key[:32]
-
- # If key size is 16, 24 or 32 bytes then padding is not required
- if len(key) in (16, 24, 32):
- return key
-
- # Add padding to make key 32 bytes long
- return key.ljust(32, padding_string)
-
-
- def pqencryptpassword(password, user):
- """
- pqencryptpassword -- to encrypt a password
- This is intended to be used by client applications that wish to send
- commands like ALTER USER joe PASSWORD 'pwd'. The password need not
- be sent in cleartext if it is encrypted on the client side. This is
- good because it ensures the cleartext password won't end up in logs,
- pg_stat displays, etc. We export the function so that clients won't
- be dependent on low-level details like whether the enceyption is MD5
- or something else.
-
- Arguments are the cleartext password, and the SQL name of the user it
- is for.
-
- Return value is "md5" followed by a 32-hex-digit MD5 checksum..
-
- Args:
- password:
- user:
-
- Returns:
-
- """
-
- m = hashlib.md5()
-
- # Place salt at the end because it may be known by users trying to crack
- # the MD5 output.
- # Handling of non-ascii password (Python2)
- if hasattr(str, 'decode'):
- password = password.encode('utf-8')
- user = user.encode('utf-8')
- else:
- password = password.encode()
- user = user.encode()
-
- m.update(password)
- m.update(user)
-
- return "md5" + m.hexdigest()
|