Hardcoded salt to fix crypto

This commit is contained in:
Manuel Ebert 2015-04-04 17:50:44 +11:00
parent 1a65ae57cb
commit 2615070df0
12 changed files with 60 additions and 54 deletions

View file

@ -4,14 +4,16 @@ from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
import base64
import os
def make_key(password):
if type(password) is unicode:
password = password.encode('utf-8')
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=os.urandom(16),
# Salt is hard-coded
salt='\xf2\xd5q\x0e\xc1\x8d.\xde\xdc\x8e6t\x89\x04\xce\xf8',
iterations=100000,
backend=default_backend()
)
@ -33,7 +35,6 @@ class EncryptedJournal(Journal.Journal):
try:
return Fernet(key).decrypt(journal_encrypted).decode('utf-8')
except (InvalidToken, IndexError):
print base64.urlsafe_b64decode(journal_encrypted)
return None
return util.get_password(keychain=self.name, validator=validate_password)

8
jrnl/__main__.py Normal file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env python
# encoding: utf-8
from __future__ import absolute_import, unicode_literals
from . import cli
if __name__ == "__main__":
cli.run()

View file

@ -18,9 +18,9 @@ import argparse
import sys
import logging
PYCRYPTO = install.module_exists("Crypto")
log = logging.getLogger(__name__)
def parse_args(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--version', dest='version', action="store_true", help="prints version information and exits")
@ -131,9 +131,11 @@ def update_config(config, new_config, scope, force_local=False):
def configure_logger(debug=False):
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO,
format='%(levelname)-8s %(name)-12s %(message)s')
logging.getLogger('parsedatetime').setLevel(logging.INFO) # disable parsedatetime debug logging
logging.basicConfig(
level=logging.DEBUG if debug else logging.INFO,
format='%(levelname)-8s %(name)-12s %(message)s'
)
logging.getLogger('parsedatetime').setLevel(logging.INFO) # disable parsedatetime debug logging
def run(manual_args=None):
@ -156,10 +158,6 @@ def run(manual_args=None):
log.debug('Using configuration "%s"', config)
original_config = config.copy()
# check if the configuration is supported by available modules
if config['encrypt'] and not PYCRYPTO:
util.prompt("According to your jrnl_conf, your journal is encrypted, however PyCrypto was not found. To open your journal, install the PyCrypto package from http://www.pycrypto.org.")
sys.exit(1)
# If the first textual argument points to a journal file,
# use this!
@ -251,9 +249,6 @@ def run(manual_args=None):
exporter = plugins.get_exporter(args.export)
print(exporter.export(journal, args.output))
elif (args.encrypt is not False or args.decrypt is not False) and not PYCRYPTO:
util.prompt("PyCrypto not found. To encrypt or decrypt your journal, install the PyCrypto package from http://www.pycrypto.org.")
elif args.encrypt is not False:
encrypt(journal, filename=args.encrypt)
# Not encrypting to a separate file: update config!

View file

@ -80,14 +80,15 @@ def load_or_install_jrnl():
config_path = CONFIG_FILE_PATH if os.path.exists(CONFIG_FILE_PATH) else CONFIG_FILE_PATH_FALLBACK
if os.path.exists(config_path):
log.debug('Reading configuration from file %s', config_path)
config = util.load_config(CONFIG_FILE_PATH)
upgrade.upgrade_jrnl_if_necessary(CONFIG_FILE_PATH)
config = util.load_config(config_path)
upgrade.upgrade_jrnl_if_necessary(config_path)
upgrade_config(config)
return config
else:
log.debug('Configuration file not found, installing jrnl...')
install()
def install():
def autocomplete(text, state):
expansions = glob.glob(os.path.expanduser(os.path.expandvars(text)) + '*')
@ -104,18 +105,14 @@ def install():
default_config['journals']['default'] = os.path.expanduser(os.path.expandvars(journal_path))
# Encrypt it?
if module_exists("Crypto"):
password = getpass.getpass("Enter password for journal (leave blank for no encryption): ")
if password:
default_config['encrypt'] = True
if util.yesno("Do you want to store the password in your keychain?", default=True):
util.set_keychain("default", password)
else:
util.set_keychain("default", None)
print("Journal will be encrypted.")
else:
password = None
print("PyCrypto not found. To encrypt your journal, install the PyCrypto package from http://www.pycrypto.org or with 'pip install pycrypto' and run 'jrnl --encrypt'. For now, your journal will be stored in plain text.")
password = getpass.getpass("Enter password for journal (leave blank for no encryption): ")
if password:
default_config['encrypt'] = True
if util.yesno("Do you want to store the password in your keychain?", default=True):
util.set_keychain("default", password)
else:
util.set_keychain("default", None)
print("Journal will be encrypted.")
path = os.path.split(default_config['journals']['default'])[0] # If the folder doesn't exist, create it
try:
@ -125,8 +122,8 @@ def install():
open(default_config['journals']['default'], 'a').close() # Touch to make sure it's there
save_config(config)
config = default_config
save_config(config)
if password:
config['password'] = password
return config

View file

@ -12,23 +12,27 @@ from cryptography.fernet import Fernet
def upgrade_encrypted_journal(filename, key_plain):
"""Decrypts a journal in memory using the jrnl 1.x encryption scheme
and returns it in plain text."""
util.prompt( "UPGRADING JOURNAL")
util.prompt("UPGRADING JOURNAL")
print "UPGRADING SHIT", filename, key_plain
with open(filename) as f:
iv_cipher = f.read()
iv, cipher = iv_cipher[:16], iv_cipher[16:]
decryption_key = hashlib.sha256(key_plain.encode('utf-8')).digest()
decryptor = Cipher(algorithms.AES(decryption_key), modes.CBC(iv), default_backend())
plain_padded = decryptor.update(cipher)
decryptor = Cipher(algorithms.AES(decryption_key), modes.CBC(iv), default_backend()).decryptor()
try:
plain_padded += decryptor.finalize()
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
plain = unpadder.update(plain_padded)
plain += unpadder.finalize()
except ValueError:
plain_padded = decryptor.update(cipher) + decryptor.finalize()
if plain_padded[-1] == " ":
# Ancient versions of jrnl. Do not judge me.
plain = plain_padded.rstrip(" ")
else:
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
plain = unpadder.update(plain_padded) + unpadder.finalize()
except IndexError:
print "UH NO"
return None
print "PLain", plain
key = EncryptedJournal.make_key(key_plain)
journal = Fernet(key).encrypt(plain.encode('utf-8'))
journal = Fernet(key).encrypt(plain)
with open(filename, 'w') as f:
f.write(journal)
return plain

View file

@ -110,8 +110,7 @@ def load_config(config_path):
"""Tries to load a config file from YAML.
"""
with open(config_path) as f:
config = yaml.load(f)
return config
return yaml.load(f)
def get_text_from_editor(config, template=""):