Package: aes-cipher
AES CipherIntroductionAES cipher is a library to encrypt/decrypt using AES256-CBC. It is possible to encrypt/decrypt both files and raw data (string or bytes).How it worksA master key and IV are derived from the given password and (optionally) salt using a key derivation function. The key derivation function can be chosen among the provided ones:PBKDF2-SHA512ScryptAlternatively, it can also be customized by the user by simply implementing theIKeyDerivatorinterface.Salt is randomly generated (16-byte long) if not specified.A random key and IV are generated and used to encrypt the actual data. In this way, if the same file is encrypted with the same password multiple times, the encrypted file will always be different.The random key and IV are encrypted with the master key and IVHMAC-SHA256 of the encrypted key/IV and file data is computed to ensure integrity, using the master key as keyIt is possible to specify either a single password or a list of passwords.
In the last case, the file will be encrypted multiple times with a different password and salt each time.InstallationThe package requires Python >= 3.7.To install it:Usingsetuptools:python setup.py installUsingpip:pip install aes_cipherTest and CoverageInstall develop dependencies:pip install -r requirements-dev.txtTo run tests:python -m unittest discoverTo run tests with coverage:coverage run -m unittest discover
coverage reportAPIsKey derivationPbkdf2Sha512class: derive keys using PBKDF2-SHA512 algorithmPbkdf2Sha512(itr_num): construct the classitr_num: iterations numberFor default values, thePbkdf2Sha512Defaultclass instance can be used:Pbkdf2Sha512Default = Pbkdf2Sha512(512 * 1024)Scryptclass: derive keys using Scrypt algorithmScrypt(n, p, r): construct the classn: CPU/Memory cost parameterp: block size parameterr: parallelization parameterFor default values, theScryptDefaultclass instance can be used:ScryptDefault = Scrypt(16384, 8, 8)To add a custom key derivation function, theIKeyDerivatorinterface shall be implemented:class IKeyDerivator(ABC):
    @abstractmethod
    def DeriveKey(self,
                  password: Union[str, bytes],
                  salt: Union[str, bytes]) -> bytes:
        passThe only requirement is that the output of theDeriveKeymethod is at least 48-byte long.A constructor can be added to customize the algorithm.EncryptionDataEncrypterclass: encrypt bytes or string dataDataEncrypter(key_derivator): construct the classkey_derivator: key derivator to be used for master key and IV generation, it shall be an instance of theIKeyDerivatorinterface. Default value:Pbkdf2Sha512Default.DataEncrypter.Encrypt(data, passwords [, salts]): encrypt data with the specified passwords and saltsdata: input data (string or bytes)passwords: list of passwords (list of strings)salts(optional): list of salts (list of strings). The number of salts shall be the same of the passwords. If not specified, salts will be randomly generated (16-byte long).DataEncrypter.GetEncryptedData(): get encrypted data (bytes)FileEncrypterclass: encrypt a fileFileEncrypter(key_derivator): construct the classkey_derivator: seeDataEncrypterconstructorFileEncrypter.Encrypt(file_in, passwords [, salts]): encrypt file with the specified passwords and saltsfile_in: input filepasswords: seeDataEncrypter.Encryptsalts: seeDataEncrypter.EncryptFileEncrypter.GetEncryptedData(): get encrypted data (bytes)FileEncrypter.SaveTo(file_out): save to filefile_out: output file to be savedDecryptionDataDecrypterclass: decrypt bytes or string dataDataDecrypter(key_derivator): construct the classkey_derivator: key derivator to be used for master key and IV generation, it shall be an instance of theIKeyDerivatorinterface. Default value:Pbkdf2Sha512Default.DataDecrypter.Decrypt(data, passwords): decrypt data with the specified passwordsdata: input data (string or bytes)passwords: seeDataEncrypter.EncryptDataDecrypter.GetDecryptedData(): get decrypted data (bytes)FileDecrypterclass: decrypt a fileFileDecrypter(key_derivator): construct the classkey_derivator: seeDataDecrypterconstructorFileDecrypter.Decrypt(file_in, passwords)file_in: input filepasswords: seeDataDecrypter.DecryptFileDecrypter.GetDecryptedData(): get decrypted data (bytes)FileDecrypter.SaveTo(file_out): save to filefile_out: output file to be savedExamplesData encryption with single password and random salt, using PBKDF2-SHA512 algorithm with default values:data_encrypter = DataEncrypter(Pbkdf2Sha512Default)
data_encrypter.Encrypt(data, "test_pwd")
enc_data = data_encrypter.GetEncryptedData()Data encryption with single password and custom salt, using PBKDF2-SHA512 algorithm with custom values:data_encrypter = DataEncrypter(
    Pbkdf2Sha512(1024 * 1024)
)
data_encrypter.Encrypt(data, ["test_pwd"], ["test_salt"])
enc_data = data_encrypter.GetEncryptedData()Data encryption with multiple passwords and custom salts, using Scrypt algorithm with default values:data_encrypter = DataEncrypter(ScryptDefault)
data_encrypter.Encrypt(data, ["test_pwd_1", "test_pwd_2"], ["test_salt_1", "test_salt_2"])
enc_data = data_encrypter.GetEncryptedData()Data decryption with single password and random salt:data_decrypter = DataDecrypter()
data_decrypter.Decrypt(data, ["test_pwd"])
dec_data = data_decrypter.GetDecryptedData()Data decryption with multiple passwords and custom salts:data_decrypter = DataDecrypter()
data_decrypter.Decrypt(data, ["test_pwd_1", "test_pwd_2"], ["test_salt_1", "test_salt_2"])
dec_data = data_decrypter.GetDecryptedData()File encryption with single password and random salt:file_encrypter = FileEncrypter()
file_encrypter.Encrypt(file_in, "test_pwd")
file_encrypter.SaveTo(file_out)Enable logging:data_encrypter = DataEncrypter()
data_encrypter.Logger().SetLevel(logging.INFO)

data_decrypter = DataDecrypter()
data_decrypter.Logger().SetLevel(logging.INFO)Sample ApplicationA sample application based on the library using the PBKDF2-SHA512 algorithm can be found in theappfolder.Basic usage:python aes_cipher_app.py -m <enc:dec> -p <password1,password2,...> -i <input_files_or_folder> -o <output_folder> [-s <salt1,salt2,...>] [-t <itr_num>] [-v] [-h]Parameters description:Short nameLong nameDescription-m--modeOperational mode:encfor encrypting,decfor decrypting-p--passwordPassword used for encrypting/decrypting. It can be a single password or a list of passwords separated by a comma-i--inputInput to be encrypted/decrypted. It can be a single file, a list of files separated by a comma or a folder (in this case all files in the folder will be encrypted/decrypted)-o--outputOutput folder where the encrypted/decrypted files will be saved-s--saltOptional: custom salts for master key and IV derivation, random if not specified`-t--iterationOptional: number of iteration for the PBKDF2-SHA512 algorithm, default value: 524288-v--verboseOptional: enable verbose mode-h--helpOptional: print usage and exitNOTE:the password shall not contain spaces or commas (in this case it will be interpreted as multiple passwords)Examples:Encrypt a file one time with the given password and salt. Ifinput_fileis a folder, all the files inside the folder will be encrypted:python aes_cipher_app.py -m enc -p test_pwd -i input_file -o encrypted -s test_saltDecrypt the previous file:python aes_cipher_app.py -m dec -p test_pwd -i encrypted -o decrypted -s test_saltEncrypt multiple files one time with the given password and salt. If one of the input files is a directory, it will be discarded:python aes_cipher_app.py -m enc -p test_pwd -i input_file1,input_file2,input_file3 -o encrypted -s test_saltEncrypt a file 3 times using 3 passwords with random salts and custom number of iteration:python aes_cipher_app.py -m enc -p test_pwd_1,test_pwd_2,test_pwd_3 -t 131072 -i input_file -o encryptedDecrypt the previous file:python aes_cipher_app.py -m dec -p test_pwd_1,test_pwd_2,test_pwd_3 -t 131072 -i encrypted -o decrypted