Skip to content

Commit

Permalink
Implement #111 - OpenSSL aes-256-cbc decryption (with pbkdf2)
Browse files Browse the repository at this point in the history
  • Loading branch information
clach04 committed Dec 30, 2023
1 parent 2b8ec48 commit a0ad483
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 1 deletion.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Plain text notes search/edit tool that supports encrypted files, formats:
* AES-256-CTR PBKDF2 (iterations 1000)
* [ccrypt](https://ccrypt.sourceforge.net/) - Rijndael-256 (no authentication)
* [GnuPG (OpenPGP, gpg)](https://www.gnupg.org/) - [symmetric](https://www.gnupg.org/gph/en/manual/r656.html) see https://tutonics.com/articles/gpg-encryption-guide-part-4-symmetric-encryption/#:~:text=Another%20type%20of%20cryptographic%20solution,also%20called%20a%20shared%20secret.
* [OpenSSL 1.1.1 aes-256-cbc](https://github.com/openssl/openssl) - [symmetric](https://www.openssl.org/docs/manmaster/man1/openssl.html) AES-256-CBC encryption with pbkdf2.
* [Tombo (chi)](https://github.com/clach04/chi_io?tab=readme-ov-file) - blowfish-ECB
* [vim VimCrypt](https://vimdoc.sourceforge.net/htmldoc/editing.html#encryption) encrypted files READ ONLY - VimCrypt (1-3) zip, blowfish, and blowfish2

Expand Down Expand Up @@ -180,6 +181,7 @@ Also see https://github.com/clach04/puren_tonbo/wiki/tool-ptig
aes256.zip - ZipAES - AES-256 ZIP AE-1 DEFLATED (regular compression)
aeszip - ZipAES - AES-256 ZIP AE-1 DEFLATED (regular compression)
old.zip - ZipAES - AES-256 ZIP AE-1 DEFLATED (regular compression)
openssl_aes256cbc_pbkdf2_10k - OpenSslEnc10k - OpenSSL 1.1.1 pbkdf2 iterations 10000 aes-256-cbc
aes256stored.zip - ZipNoCompressionAES - AES-256 ZIP AE-1 STORED (uncompressed)
oldstored.zip - ZipNoCompressionAES - AES-256 ZIP AE-1 STORED (uncompressed)
aes256lzma.zip - ZipLzmaAES - AES-256 ZIP AE-1 LZMA
Expand Down Expand Up @@ -342,6 +344,25 @@ Requires a gpg binary, download from https://gnupg.org/download/

Also see `encryptcli` from https://github.com/evpo/EncryptPad/

#### OpenSSL 1.1.1 AES

OpenSSL 1.1.1 compatible (with a very small subset of options).

ptcat --note-root=. puren_tonbo/tests/data/aesop_win.openssl_aes256cbc_pbkdf2_10k

Intended to allow decryption of files generated with OpenSSL 1.1.1 and vice-versa. Supported OpenSSL flags/formats:

openssl enc -e aes-256-cbc -salt -pbkdf2 -iter 10000 -in in_file -base64 -out out_file
openssl dec -d aes-256-cbc -salt -pbkdf2 -iter 10000 -in in_file -base64 -out out_file

echo hello| openssl enc -e aes-256-cbc -salt -pbkdf2 -iter 10000 -in - -base64 -out - -pass pass:password
echo hello| openssl enc -e -aes-256-cbc -in - -out - -salt -pbkdf2 -iter 10000 -pass pass:password

NOTE PBKDF2 iteration count of 10,000 is the default in OpenSSL 1.1.1 and is considered too few in 2023.
Older versions of OpenSSL did not support; PBKDF2 (and ergo iterations) and salt and used a much weaker KDF.

Supports binary/raw and base64 encoded/ASCII armored files.
ONLY supports aes-256-cbc with salt and pbkdf2 KDF with 10,000 interations.

#### AES-256 zip

Expand Down
26 changes: 26 additions & 0 deletions puren_tonbo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def __bool__(self):
except ImportError:
keyring = fake_module('keyring')

try:
from openssl_enc_compat.cipher import OpenSslEncDecCompat # https://github.com/clach04/openssl_enc_compat/
except ImportError:
OpenSslEncDecCompat = fake_module('openssl_enc_compat')

try:
import pyzipper # https://github.com/danifus/pyzipper NOTE py3 only
except ImportError:
Expand Down Expand Up @@ -419,6 +424,23 @@ def write_to(self, file_object, byte_data):
file_object.write(enc_data.data)


class OpenSslEnc10k(EncryptedFile):
description = 'OpenSSL 1.1.1 pbkdf2 iterations 10000 aes-256-cbc'
extensions = [
'.openssl_aes256cbc_pbkdf2_10k', # generated via openssl enc -e -aes-256-cbc -in plain_in -out crypted_out.openssl_aes256cbc_pbkdf2_10k -salt -pbkdf2 -iter 10000
]
# TODO KeepOut .kpt files - https://antofthy.gitlab.io/software/keepout.sh.txt

def read_from(self, file_object):
# TODO catch exceptions and raise PurenTonboException()
data = file_object.read()
password = self.key
if not isinstance(password, bytes):
password = password.decode("utf-8")
cipher = OpenSslEncDecCompat(password)
plaintext = cipher.decrypt(data) # guesses if base64 encoded or note
return plaintext

class TomboBlowfish(EncryptedFile):
"""Read/write Tombo (modified) Blowfish encrypted files
Compatible with files in:
Expand Down Expand Up @@ -596,6 +618,10 @@ class ZipBzip2AES(ZipAES):
for enc_class in (PurePyZipAES, ZipNoCompressionPurePyZipAES):
for file_extension in enc_class.extensions:
file_type_handlers[file_extension] = enc_class
if OpenSslEncDecCompat:
for enc_class in (OpenSslEnc10k, ):
for file_extension in enc_class.extensions:
file_type_handlers[file_extension] = enc_class
if pyzipper: # potentially overwrite PurePyZipAES and ZipNoCompressionPurePyZipAES as default zip support
for enc_class in (ZipAES, ZipNoCompressionAES, ZipLzmaAES, ZipBzip2AES):
for file_extension in enc_class.extensions:
Expand Down
5 changes: 5 additions & 0 deletions puren_tonbo/tests/data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ Ideally generated with external tools that Puren Tonbo can validate against.
* Approx 1.5Kb.
* Command: type aesop.txt | ccrypt -e > aesop_win_ccrypt.cpt

* aesop_win.openssl_aes256cbc_pbkdf2_10k - OpenSSL aes-256-cbc pbkdf2 encrypted from `aesop.txt`
Created with Windows win64 with windows-git openssl.exe - `"C:\Program Files\Git\mingw64\bin\openssl.exe" enc -e -aes-256-cbc -in aesop.txt -out aesop_win.openssl_aes256cbc_pbkdf2_10k -salt -pbkdf2 -iter 10000 -pass pass:password`
* password is `password`
* Approx 1.1Kb.

* aesop_win_encryptpad.asc - gpg (GnuPG) encrypted from `aesop.txt`
Created with Windows win32 encryptpad 0.5.0.2 beta https://github.com/evpo/EncryptPad/
* password is `password`
Expand Down
Binary file not shown.
1 change: 1 addition & 0 deletions puren_tonbo/tests/testsuite.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ def test_aesop_linux_vimcrypt1(self):
data = note_root.note_contents(test_note_filename, password)
self.assertEqual(self.plain_text_data_linux_newlines, data)

# TODO test openssl_aes256cbc_pbkdf2_10k

# Tests write/encryption to disk

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ keyring==18.0.1 # last py2.7 and Py3 compat version
pycryptodome # for performance - actually used by pyzipper so not explictly needed
pyzipper; python_version > "2.7"
python-gnupg
openssl_enc_compat # https://github.com/clach04/openssl_enc_compat/
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@


# TODO/FIXME dupe of requirements.txt - also chi_io missing here (as not on pypi)
install_requires = ['colorama', 'pycryptodome', 'python-gnupg']
install_requires = ['colorama', 'pycryptodome', 'python-gnupg', 'openssl_enc_compat']
if is_py3:
install_requires += ['pyzipper'] # pyzipperis python 3.x+
# TODO consider extras_require, for things like; pyvim, python-gnupg, chi_io
Expand Down

0 comments on commit a0ad483

Please sign in to comment.