codekingpro/portable-devtools
114k
1##########################################################################2#3# pgAdmin 4 - PostgreSQL Tools4#5# Copyright (C) 2013 - 2024, The pgAdmin Development Team6# This software is released under the PostgreSQL Licence7#8#########################################################################9 10"""This File Provides Cryptography."""11 12import base6413import hashlib14import os15 16from cryptography.hazmat.backends import default_backend17from cryptography.hazmat.primitives.ciphers import Cipher18from cryptography.hazmat.primitives.ciphers.algorithms import AES19from cryptography.hazmat.primitives.ciphers.modes import CFB820 21padding_string = b'}'22iv_size = AES.block_size // 823 24 25def encrypt(plaintext, key):26 """27 Encrypt the plaintext with AES method.28 29 Parameters:30 plaintext -- String to be encrypted.31 key -- Key for encryption.32 """33 34 iv = os.urandom(iv_size)35 cipher = Cipher(AES(pad(key)), CFB8(iv), default_backend())36 encryptor = cipher.encryptor()37 38 # If user has entered non ascii password (Python2)39 # we have to encode it first40 if isinstance(plaintext, str):41 plaintext = plaintext.encode()42 43 return base64.b64encode(iv + encryptor.update(plaintext) +44 encryptor.finalize())45 46 47def decrypt(ciphertext, key):48 """49 Decrypt the AES encrypted string.50 51 Parameters:52 ciphertext -- Encrypted string with AES method.53 key -- key to decrypt the encrypted string.54 """55 56 ciphertext = base64.b64decode(ciphertext)57 iv = ciphertext[:iv_size]58 59 cipher = Cipher(AES(pad(key)), CFB8(iv), default_backend())60 decryptor = cipher.decryptor()61 return decryptor.update(ciphertext[iv_size:]) + decryptor.finalize()62 63 64def pad(key):65 """Add padding to the key."""66 67 if isinstance(key, str):68 key = key.encode()69 70 # Key must be maximum 32 bytes long, so take first 32 bytes71 key = key[:32]72 73 # If key size is 16, 24 or 32 bytes then padding is not required74 if len(key) in (16, 24, 32):75 return key76 77 # Add padding to make key 32 bytes long78 return key.ljust(32, padding_string)79 80 81def pqencryptpassword(password, user):82 """83 pqencryptpassword -- to encrypt a password84 This is intended to be used by client applications that wish to send85 commands like ALTER USER joe PASSWORD 'pwd'. The password need not86 be sent in cleartext if it is encrypted on the client side. This is87 good because it ensures the cleartext password won't end up in logs,88 pg_stat displays, etc. We export the function so that clients won't89 be dependent on low-level details like whether the enceyption is MD590 or something else.91 92 Arguments are the cleartext password, and the SQL name of the user it93 is for.94 95 Return value is "md5" followed by a 32-hex-digit MD5 checksum..96 97 Args:98 password:99 user:100 101 Returns:102 103 """104 105 m = hashlib.md5()106 107 # Place salt at the end because it may be known by users trying to crack108 # the MD5 output.109 110 m.update(password.encode())111 m.update(user.encode())112 113 return "md5" + m.hexdigest()114 