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:
#!/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?
-
1\$\begingroup\$ Have you looked at the keyring module? That provides access to the system keychain for storing passwords, which is probably better than rolling your own crypto. \$\endgroup\$alexwlchan– alexwlchan2015年09月24日 13:32:25 +00:00Commented Sep 24, 2015 at 13:32
-
\$\begingroup\$ @alexwlchan Huh! I googled, of course - but doesn't found this mod :-( Thanks... Seems I reinvented the bicycle :-) \$\endgroup\$setevoy– setevoy2015年09月24日 13:34:29 +00:00Commented Sep 24, 2015 at 13:34
1 Answer 1
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.
Explore related questions
See similar questions with these tags.