Passwords storage class I'm writing a tool, to manage our application, specifically to store passwords in encrypted view. I made a class which is based on two posts:

https://stackoverflow.com/questions/20852664/python-pycrypto-encrypt-decrypt-text-files-with-aes

and:

https://stackoverflow.com/questions/4102761/python-config-parser-cache-to-reduce-i-o-on-an-embedded-system

#!/usr/bin/env python

import os

import StringIO
import hashlib

from Crypto import Random
from Crypto.Cipher import AES

from lib.shared import ConfigParser


class RDSCryptor(object):

    def __init__(self, rdsmanager_local_path):

        password = 'password'
        self.key = hashlib.sha256(password).digest()

        self.passfile_enc = os.path.join(rdsmanager_local_path, 'conf', 'credentials.txt.enc')
        self.passfile_clear = os.path.join(rdsmanager_local_path, 'conf', 'credentials.txt')

    def pad(self, s):

        return s + b"\0" * (AES.block_size - len(s) % AES.block_size)

    def encrypt(self, message):

        message = self.pad(message)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)

        return iv + cipher.encrypt(message)

    def decrypt(self, ciphertext):

        iv = ciphertext[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        plaintext = cipher.decrypt(ciphertext[AES.block_size:])

        return plaintext.rstrip(b"\0")

    def encrypt_file(self):

        with open(self.passfile_enc, 'rb') as fo:
            plaintext = fo.read()
        enc = self.encrypt(plaintext)

        with open(self.passfile_enc + '.enc', 'wb') as fo:
            fo.write(enc)

    def decrypt_file(self):

        with open(self.passfile_enc, 'rb') as fo:
            ciphertext = fo.read()

        dec = self.decrypt(ciphertext)

        return dec

    def get_credentials(self, section, option):

        buf = StringIO.StringIO(self.decrypt_file())

        config = ConfigParser.ConfigParser()
        config.readfp(buf)

        return config.get(section, option)


Cleartext file (it's not stored in project's repository) looks like:


[cloudlibrary]
clc_user = username
clc_password = password

[kantar_smtp]
smtpconnect_user = username
smtpconnect_password = password



Thet - this class used in main tool's script with:

...
# Cloudlibrary access data
crypto = RDSCryptor(rdsmanager_local_path)

clc_user = crypto.get_credentials('cloudlibrary', 'clc_user')
clc_password = crypto.get_credentials('cloudlibrary', 'clc_password')

# Sendmail credentials
smtpconnect_user = crypto.get_credentials('kantar_smtp', 'smtpconnect_user')
smtpconnect_password = crypto.get_credentials('kantar_smtp', 'smtpconnect_password')
...


All I want is to hide plaintext from the source code - it's not intended to be super-secure against hackers.

What is wrong or can it be done better here?
You don't need to declare password to just use on the next line and never again. Use the literal directly:

self.key = hashlib.sha256('password').digest()


You have some confusing names, like s and iv. Renaming these to be more explicit, like string for s would make it more readable. As would adding docstrings or (less preferably) comments to explain the context of what each function is exactly. At the very least your overall class should have a docstring for a user to know about the general practice of the class.