How To decrypt mysql_config_editor file my.cnf using python

 How To decrypt  mysql_config_editor file my.cnf using python 

from configparser import RawConfigParser

import os

import struct

import sys


from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

from cryptography.hazmat.backends import default_backend


VERSION = (0, 0, 2)


# Buffer at the beginning of the login path file.

_UNUSED_BUFFER_LENGTH = 4


# The key stored in the file.

_LOGIN_KEY_LENGTH = 20


# Number of bytes used to store the length of ciphertext.

_CIPHER_STORE_LENGTH = 4



def read(path=None) -> str:

    """Read contents of the login path file."""

    if path is None:

        path = _get_login_path_file()

    with open(path, "rb") as fp:

        return _read_encrypted_file(fp).decode()



def parse(login_path: str, path=None) -> dict:

    if path is None:

        path = _get_login_path_file()

        #path = 'D:\.mylogin.cnf'

    parser = RawConfigParser(

        dict_type=dict, allow_no_value=True, default_section="~~~UNUSED~~~"

    )

    parser.read_string(read(path), source=path)

    data = dict(parser.items(login_path))

    data = {key: _strip_quotes(value) for key, value in data.items()}

    if "port" in data:

        data["port"] = int(data["port"])

    return data



def _get_login_path_file():

    """Return the login path file's path or None if it doesn't exist."""

    file_path = os.getenv("MYSQL_TEST_LOGIN_FILE")

    if file_path:

        return file_path


    if sys.platform == "win32":

        #file_path = os.path.join(os.getenv("APPDATA"), "MySQL", ".mylogin.cnf")

        file_path = 'D:\.mylogin.cnf'

    else:

        file_path = os.path.join("~", ".mylogin.cnf")

    return os.path.expanduser(file_path)



def _read_key(fp):

    """Read the key from the login path file header."""

    # Move past the unused buffer.

    _buffer = fp.read(_UNUSED_BUFFER_LENGTH)


    if not _buffer or len(_buffer) != _UNUSED_BUFFER_LENGTH:

        # Login path file is blank or incomplete.

        return None


    return _create_key(fp.read(_LOGIN_KEY_LENGTH))



def _create_key(key):

    """Create the AES key from the login path file header."""

    rkey = bytearray(16)

    for i in range(len(key)):

        rkey[i % 16] ^= key[i]

    return bytes(rkey)



def _get_aes_cipher(key):

    """Get the AES cipher object."""

    return Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())



def _read_encrypted_file(f) -> bytes:

    """Decrypt a file *f*."""

    key = _read_key(f)

    cipher = _get_aes_cipher(key)

    decryptor = cipher.decryptor()


    plaintext = b""


    while True:

        # Read the length of the line.

        length_buffer = f.read(_CIPHER_STORE_LENGTH)

        if len(length_buffer) < _CIPHER_STORE_LENGTH:

            break

        (line_length,) = struct.unpack("<i", length_buffer)

        line = _read_line(f, line_length, decryptor)

        plaintext += line


    return plaintext



def _read_line(f, length, decryptor):

    """Read a line of length *length* from file *f* using *decryptor*."""

    line = f.read(length)

    return _remove_pad(decryptor.update(line))



def _remove_pad(line):

    """Remove the pad from the *line*."""

    try:

        pad_length = ord(line[-1:])

    except TypeError:

        # ord() was unable to get the value of the byte.

        return None


    if pad_length > len(line):

        # Pad length should be less than or equal to the length of the

        # plaintext.

        return None


    return line[:-pad_length]



def _strip_quotes(value):

    """If a value is quoted, remove the quotes at the beginning and end, then

    un-escape any quote characters inside the string."""

    if value.startswith('"') and value.endswith('"'):

        # This is a quoted string. Remove the first and

        # last quote, then unescape interior quotes.

        value = value[1:-1]

        value = value.replace('\\"', '"')

    return value



if __name__ == "__main__":

    print(read())

    #print(parse("test"))

Comments

Popular posts from this blog

MySQL Replication Switchover: Step-by-Step Guide

How To Install and Configure Innodb Cluster /shell/Router

How to create database manually in oracle 11g R2