0.6.1 - This version may not be safe as it has not been updated for a long time. Find out if your coding project uses this component and get notified of any reported security vulnerabilities with Meterian-X Open Source Security Platform
Maintain your licence declarations and avoid unwanted licences to protect your IP the way you intended.
GPL-3.0-only - GNU General Public License v3.0 only|pypi-badge| |ci-badge|
This module implements the Blowfish cipher using only Python (3.4+).
Blowfish is a block cipher that can be used for symmetric-key encryption. It has a 8-byte block size and supports a variable-length key, from 4 to 56 bytes. It's fast, free and has been analyzed considerably. It was designed by Bruce Schneier and more details about it can be found at https://www.schneier.com/blowfish.html.
.. contents:: :local: :backlinks: top
If you just need a Blowfish cipher in your Python project, feel free to
manually copy blowfish.py to your package directory (license permitting).
distutils
#########
To install the module to your Python distribution, use the included
distutils script::
$ python setup.py install
pip
Stable versions can be installed from pypi_ using pip::
$ pip install blowfish
pip can also install the latest development version directly from git::
$ pip install 'git+https://github.com/jashandeep-sohi/python-blowfish.git'
.. _pypi: https://pypi.python.org/pypi/blowfish
Want to add a mode of operation? Speed up encryption?
Make your changes to a clone of the repository at https://github.com/jashandeep-sohi/python-blowfish and send me a pull request.
Tests are written using the Python unittest framework. All tests currently
reside in the test.py file and can be run using the distutils script::
$ python setup.py test
Are you having problems? Please let me know at https://github.com/jashandeep-sohi/python-blowfish/issues
.. warning::
Cryptography is complex, so please don't use this module in anything
*critical* without understanding what you are doing and checking the source
code to make sure it is doing what you want it to.
.. note::
This is just a quick overview on how to use the module. For detailed
documentation please see the `docstrings` in the module.
First create a Cipher object with a key.
.. code:: python3
import blowfish
cipher = blowfish.Cipher(b"Key must be between 4 and 56 bytes long.")
By default this initializes a Blowfish cipher that will interpret bytes using
the big-endian byte order. Should the need arrise to use the little-endian byte
order, provide "little" as the second argument.
.. code:: python3
cipher_little = blowfish.Cipher(b"my key", byte_order = "little")
Block
To encrypt or decrypt a block of data (8 bytes), use the encrypt_block or
decrypt_block methods of the Cipher object.
.. code:: python3
from os import urandom
block = urandom(8)
ciphertext = cipher.encrypt_block(block)
plaintext = cipher.decrypt_block(ciphertext)
assert block == plaintext
As these methods can only operate on 8 bytes of data, they're of little practical use. Instead, use one of the implemented modes of operation.
Cipher-Block Chaining Mode (CBC)
################################
To encrypt or decrypt data in CBC mode, use encrypt_cbc or decrypt_cbc
methods of the Cipher object. CBC mode can only operate on data that is a
multiple of the block-size in length.
.. code:: python3
data = urandom(10 * 8) # data to encrypt
iv = urandom(8) # initialization vector
data_encrypted = b"".join(cipher.encrypt_cbc(data, iv))
data_decrypted = b"".join(cipher.decrypt_cbc(data_encrypted, iv))
assert data == data_decrypted
Cipher-Block Chaining with Ciphertext Stealing (CBC-CTS)
########################################################
To encrypt or decrypt data in CBC-CTS mode, use encrypt_cbc_cts or
decrypt_cbc_cts methods of the Cipher object. CBC-CTS mode can operate
on data of any length greater than 8 bytes.
.. code:: python3
data = urandom(10 * 8 + 6) # data to encrypt
iv = urandom(8) # initialization vector
data_encrypted = b"".join(cipher.encrypt_cbc_cts(data, iv))
data_decrypted = b"".join(cipher.decrypt_cbc_cts(data_encrypted, iv))
assert data == data_decrypted
Propagating Cipher-Block Chaining Mode (PCBC)
#############################################
To encrypt or decrypt data in PCBC mode, use encrypt_pcbc or decrypt_pcbc
methods of the Cipher object. PCBC mode can only operate on data that is a
multiple of the block-size in length.
.. code:: python3
data = urandom(10 * 8) # data to encrypt
iv = urandom(8) # initialization vector
data_encrypted = b"".join(cipher.encrypt_pcbc(data, iv))
data_decrypted = b"".join(cipher.decrypt_pcbc(data_encrypted, iv))
assert data == data_decrypted
Cipher Feedback Mode (CFB)
##########################
To encrypt or decrypt data in CFB mode, use encrypt_cfb or decrypt_cfb
methods of the Cipher object. CFB mode can operate on data of any length.
.. code:: python3
data = urandom(10 * 8 + 7) # data to encrypt
iv = urandom(8) # initialization vector
data_encrypted = b"".join(cipher.encrypt_cfb(data, iv))
data_decrypted = b"".join(cipher.decrypt_cfb(data_encrypted, iv))
assert data == data_decrypted
Output Feedback Mode (OFB)
##########################
To encrypt or decrypt data in OFB mode, use encrypt_ofb or decrypt_ofb
methods of the Cipher object. OFB mode can operate on data of any length.
.. code:: python3
data = urandom(10 * 8 + 1) # data to encrypt
iv = urandom(8) # initialization vector
data_encrypted = b"".join(cipher.encrypt_ofb(data, iv))
data_decrypted = b"".join(cipher.decrypt_ofb(data_encrypted, iv))
assert data == data_decrypted
Counter Mode (CTR)
##################
To encrypt or decrypt data in CTR mode, use encrypt_ctr or decrypt_ctr
methods of the Cipher object. CTR mode can operate on data of any length.
Although you can use any counter you want, a simple increment by one counter
is secure and the most popular. So for convenience sake a simple increment by
one counter is implemented by the blowfish.ctr_counter function. However,
you should implement your own for optimization purposes.
.. code:: python3
from operator import xor
data = urandom(10 * 8 + 2) # data to encrypt
# increment by one counters
nonce = int.from_bytes(urandom(8), "big")
enc_counter = blowfish.ctr_counter(nonce, f = xor)
dec_counter = blowfish.ctr_counter(nonce, f = xor)
data_encrypted = b"".join(cipher.encrypt_ctr(data, enc_counter))
data_decrypted = b"".join(cipher.decrypt_ctr(data_encrypted, dec_counter))
assert data == data_decrypted
Electronic Codebook Mode (ECB) ############################## Note: ECB mode does not provide strong confidentiality, regardless of the cipher, and is not recommended for use in applications.
To encrypt or decrypt data in ECB mode, use encrypt_ecb or decrypt_ecb
methods of the Cipher object. ECB mode can only operate on data that is a
multiple of the block-size in length.
.. code:: python3
data = urandom(10 * 8) # data to encrypt
data_encrypted = b"".join(cipher.encrypt_ecb(data))
data_decrypted = b"".join(cipher.decrypt_ecb(data_encrypted))
assert data == data_decrypted
Electronic Codebook Mode with Cipher Text Stealing (ECB-CTS) ############################################################ Note: the warning pertaining to ECB mode above also applies to ECB-CTS.
To encrypt or decrypt data in ECB-CTS mode, use encrypt_ecb_cts or
decrypt_ebc_cts methods of the Cipher object. ECB-CTS mode can operate
on data of any length greater than 8 bytes.
.. code:: python3
data = urandom(10 * 8 + 5) # data to encrypt
data_encrypted = b"".join(cipher.encrypt_ecb_cts(data))
data_decrypted = b"".join(cipher.decrypt_ecb_cts(data_encrypted))
assert data == data_decrypted
.. |pypi-badge| image:: https://img.shields.io/pypi/v/blowfish :alt: PyPI :target: https://pypi.org/project/blowfish
.. |ci-badge| image:: https://github.com/jashandeep-sohi/python-blowfish/actions/workflows/ci.yml/badge.svg :alt: CI :target: https://github.com/jashandeep-sohi/python-blowfish/actions/workflows/ci.yml