Skip to content

Commit

Permalink
Better exceptions handling, cleanup, more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Bellaccini committed Feb 11, 2017
1 parent c582648 commit 2db4468
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 122 deletions.
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
History
===============

0.2.1 (Feb 2017)
~~~~~~~~~~~~~~~~~~
* Better exceptions handling
* Code clean-up
* More unittests

0.2 (Jan 2017)
~~~~~~~~~~~~~~~~~~
* Modularized pyAesCrypt (and now the script calls the module for operations)
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ Decrypt file test.txt.aes in test2.txt:

.. _AES Crypt: https://www.aescrypt.com
.. _file format: https://www.aescrypt.com/aes_file_format.html
.. _Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
.. _Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
2 changes: 1 addition & 1 deletion THANKS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ Thanks
===============
Thanks to `Ben Fisher`_ for providing a patch to improve decryption speed.

.. _Ben Fisher: https://downpoured.github.io/
.. _Ben Fisher: https://downpoured.github.io/
72 changes: 47 additions & 25 deletions bin/pyAesCrypt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
#
#==============================================================================
# Copyright 2016 Marco Bellaccini - marco.bellaccini[at!]gmail.com
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -17,16 +17,16 @@
#==============================================================================

#==============================================================================
# pyAesCrypt 0.2
#
# pyAesCrypt is a Python file-encryption utility that uses AES256-CBC to
# pyAesCrypt
#
# pyAesCrypt is a Python file-encryption utility that uses AES256-CBC to
# encrypt/decrypt files.
# pyAesCrypt is compatible with the AES Crypt (https://www.aescrypt.com/)
# file format (version 2).
#
# IMPORTANT SECURITY NOTE: version 2 of the AES Crypt file format does not
# authenticate the "file size modulo 16" byte. This implies that an attacker
# with write access to the encrypted file may alter the corresponding plaintext
#
# IMPORTANT SECURITY NOTE: version 2 of the AES Crypt file format does not
# authenticate the "file size modulo 16" byte. This implies that an attacker
# with write access to the encrypted file may alter the corresponding plaintext
# file size by up to 15 bytes.
#
# NOTE: there is no low-level memory management in Python, hence it is
Expand All @@ -38,30 +38,37 @@
import argparse
import getpass
from sys import exit
from os.path import isfile
import pyAesCrypt

maxPassLen = 1024 # maximum password length (number of chars)
maxPassLen = 1024 # maximum password length (number of chars)

# encryption/decryption buffer size - 64K
bufferSize = 64 * 1024

# parse command line arguments
parser = argparse.ArgumentParser(description="Encrypt/decrypt a file using AES256-CBC.")
parser = argparse.ArgumentParser(description=("Encrypt/decrypt a file "
"using AES256-CBC."))
parser.add_argument("filename", type=str,
help="file to encrypt/decrypt")
parser.add_argument("-o","--out", type=str,
parser.add_argument("-o", "--out", type=str,
default=None, help="specify output file")

# encrypt OR decrypt....
groupED = parser.add_mutually_exclusive_group(required=True)
groupED = parser.add_mutually_exclusive_group(required=True)
groupED.add_argument("-e", "--encrypt",
help="encrypt file", action="store_true")
help="encrypt file", action="store_true")
groupED.add_argument("-d", "--decrypt",
help="decrypt file", action="store_true")
help="decrypt file", action="store_true")
args = parser.parse_args()


# check for input file existence
if not isfile(args.filename):
exit("Error: file \"" + args.filename + "\" was not found.")

# prompt the user for password
passw=str(getpass.getpass("Password:"))
passw = str(getpass.getpass("Password:"))

if args.encrypt:
# check against max password length
Expand All @@ -76,15 +83,16 @@ if args.encrypt:
# 1 digit
# 1 symbol
if not((len(passw) > 7) and any(c.islower() for c in passw)
and any(c.isupper() for c in passw) and any(c.isdigit() for c in passw)
and any(not(c.isalnum()) for c in passw)):
and any(c.isupper() for c in passw)
and any(c.isdigit() for c in passw)
and any(not(c.isalnum()) for c in passw)):
print("Warning: your password seems weak.")
print("A password should be at least 8 chars long and should "
"contain at least one lowercase char, one uppercase char, one "
"digit and one symbol.")
"contain at least one lowercase char, one uppercase char, "
"one digit and one symbol.")

# re-prompt the user for password
passwConf=str(getpass.getpass("Confirm password:"))
passwConf = str(getpass.getpass("Confirm password:"))

# check the second pass against the first
if passw != passwConf:
Expand All @@ -97,7 +105,14 @@ if args.encrypt:
ofname = args.filename+".aes"

# call encryption function
pyAesCrypt.encryptFile(args.filename, ofname, passw, bufferSize)
try:
pyAesCrypt.encryptFile(args.filename, ofname, passw, bufferSize)
# handle IO errors
except IOError as ex:
exit(ex)
# handle value errors
except ValueError as ex:
exit(ex)

elif args.decrypt:
# open output file
Expand All @@ -107,7 +122,14 @@ elif args.decrypt:
ofname = args.filename[:-4]
else:
exit("Error: if input file extension is not \".aes\", you should "
"provide the output file name through \"-o\" option.")
"provide the output file name through \"-o\" option.")

# call decryption function
pyAesCrypt.decryptFile(args.filename, ofname, passw, bufferSize)
try:
pyAesCrypt.decryptFile(args.filename, ofname, passw, bufferSize)
# handle IO errors
except IOError as ex:
exit(ex)
# handle value errors
except ValueError as ex:
exit(ex)
2 changes: 1 addition & 1 deletion pyAesCrypt/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .crypto import encryptFile, decryptFile
from .crypto import encryptFile, decryptFile
Loading

0 comments on commit 2db4468

Please sign in to comment.