diff --git a/sigal/plugins/encrypt/encrypt.py b/sigal/plugins/encrypt/encrypt.py index 05acc21..2c6bbf1 100644 --- a/sigal/plugins/encrypt/encrypt.py +++ b/sigal/plugins/encrypt/encrypt.py @@ -20,7 +20,8 @@ '''Plugin to protect gallery by encrypting image files using a password. -Options: +Options:: + encrypt_options = { 'password': 'password', 'ask_password': False, @@ -50,7 +51,11 @@ BUILT, or there will be inconsistency in encrypted files and viewers will not be to see some of the images any more. ''' -import os, random, string, logging, pickle +import os +import random +import string +import logging +import pickle from io import BytesIO from itertools import chain @@ -207,7 +212,7 @@ def encrypt_files(settings, config, cache, albums, progressbar_target): logger.warning("Original files are symlinked! Set encrypt_options[\"encrypt_symlinked_originals\"] to True to force encrypting them, if this is what you want.") raise Abort - key = kdf_gen_key(config["password"].encode("utf-8"), config["kdf_salt"].encode("utf-8"), config["kdf_iters"]) + key = kdf_gen_key(config["password"], config["kdf_salt"], config["kdf_iters"]) gcm_tag = config["gcm_tag"].encode("utf-8") medias = list(chain.from_iterable(albums.values())) diff --git a/sigal/plugins/encrypt/endec.py b/sigal/plugins/encrypt/endec.py index 9316fc8..8bc4f64 100644 --- a/sigal/plugins/encrypt/endec.py +++ b/sigal/plugins/encrypt/endec.py @@ -21,20 +21,24 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. +import io +import os from pathlib import Path -import os, io from base64 import b64decode +from typing import BinaryIO + from cryptography.hazmat.primitives.ciphers.aead import AESGCM from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.exceptions import InvalidTag -from typing import BinaryIO backend = default_backend() -MAGIC_STRING = "_e_n_c_r_y_p_t_e_d_" +MAGIC_STRING = "_e_n_c_r_y_p_t_e_d_".encode("utf-8") -def kdf_gen_key(password: bytes, salt:bytes, iters: int) -> bytes: +def kdf_gen_key(password: str, salt: str, iters: int) -> bytes: + password = password.encode("utf-8") + salt = salt.encode("utf-8") kdf = PBKDF2HMAC( algorithm=hashes.SHA1(), length=16, @@ -50,11 +54,7 @@ def dispatchargs(decorated): if args.key is not None: key = b64decode(args.key.encode("utf-8")) elif args.password is not None: - key = kdf_gen_key( - args.password.encode("utf-8"), - args.kdf_salt.encode("utf-8"), - args.kdf_iters - ) + key = kdf_gen_key(args.password, args.kdf_salt, args.kdf_iters) else: raise ValueError("Neither password nor key is provided") tag = args.gcm_tag.encode("utf-8") @@ -75,7 +75,7 @@ def encrypt(key: bytes, infile: BinaryIO, outfile: BinaryIO, tag: bytes): ciphertext = outfile rawbytes = plaintext.read() encrypted = aesgcm.encrypt(iv, rawbytes, tag) - ciphertext.write(MAGIC_STRING.encode("utf-8")) + ciphertext.write(MAGIC_STRING) ciphertext.write(iv) ciphertext.write(encrypted) @@ -86,7 +86,7 @@ def decrypt(key: bytes, infile: BinaryIO, outfile: BinaryIO, tag: bytes): ciphertext = infile plaintext = outfile magicstring = ciphertext.read(len(MAGIC_STRING)) - if magicstring != MAGIC_STRING.encode("utf-8"): + if magicstring != MAGIC_STRING: raise ValueError("Data is not encrypted") iv = ciphertext.read(12) rawbytes = ciphertext.read() diff --git a/tests/test_encrypt.py b/tests/test_encrypt.py index 1cc9034..8a53e7b 100644 --- a/tests/test_encrypt.py +++ b/tests/test_encrypt.py @@ -13,8 +13,8 @@ CURRENT_DIR = os.path.dirname(__file__) def get_key_tag(settings): options = settings["encrypt_options"] key = endec.kdf_gen_key( - options["password"].encode("utf-8"), - options["kdf_salt"].encode("utf-8"), + options["password"], + options["kdf_salt"], options["kdf_iters"] ) tag = options["gcm_tag"].encode("utf-8")