blowfish
========
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
Dependencies
------------
- Python 3.4+
Features
--------
- Fast (well, as fast you can possibly go using only Python 3.4+)
- Efficient; generators/iterators are used liberally to reduce memory usage
- Electronic Codebook (ECB) mode
- Electronic Codebook with Ciphertext Stealing (ECB-CTS) mode
- Cipher-Block Chaining (CBC) mode
- Cipher-Block Chaining with Ciphertext Stealing (CBC-CTS) mode
- Propagating Cipher-Block Chaining (PCBC) mode
- Cipher Feedback (CFB) mode
- Output Feedback (OFB) mode
- Counter (CTR) mode
Installation
------------
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
Development
-----------
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
-----
Tests are written using the Python `unittest` framework. All tests are in the
``test.py`` file and can be run using::
$ python -m unittest test.py
Bugs
----
Are you having problems? Please let me know at
https://github.com/jashandeep-sohi/python-blowfish/issues
Usage
-----
.. 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.
Electronic Codebook Mode (ECB)
##############################
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)
############################################################
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
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
.. vim: tabstop=2 expandtab
Raw data
{
"_id": null,
"home_page": "https://github.com/jashandeep-sohi/python-blowfish",
"name": "blowfish",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Jashandeep Sohi",
"author_email": "jashandeep.s.sohi@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/ca/06/6008f79f3df714da4eeb6d7daf5e417e072c69923d22ede09171e74d69f8/blowfish-0.6.1.tar.bz2",
"platform": "UNKNOWN",
"description": "blowfish\n========\nThis module implements the Blowfish cipher using only Python (3.4+).\n\nBlowfish is a block cipher that can be used for symmetric-key encryption. It\nhas a 8-byte block size and supports a variable-length key, from 4 to 56 bytes.\nIt's fast, free and has been analyzed considerably. It was designed by Bruce\nSchneier and more details about it can be found at\n<https://www.schneier.com/blowfish.html>.\n\n.. contents::\n :local:\n :backlinks: top\n\nDependencies\n------------\n- Python 3.4+\n\nFeatures\n--------\n- Fast (well, as fast you can possibly go using only Python 3.4+)\n- Efficient; generators/iterators are used liberally to reduce memory usage\n- Electronic Codebook (ECB) mode\n- Electronic Codebook with Ciphertext Stealing (ECB-CTS) mode\n- Cipher-Block Chaining (CBC) mode\n- Cipher-Block Chaining with Ciphertext Stealing (CBC-CTS) mode\n- Propagating Cipher-Block Chaining (PCBC) mode\n- Cipher Feedback (CFB) mode\n- Output Feedback (OFB) mode\n- Counter (CTR) mode\n\nInstallation\n------------\nIf you just need a Blowfish cipher in your Python project, feel free to\nmanually copy ``blowfish.py`` to your package directory (license permitting).\n\ndistutils\n#########\nTo install the module to your Python distribution, use the included\n`distutils` script::\n\n $ python setup.py install\n \npip\n####\nStable versions can be installed from `pypi`_ using `pip`::\n \n $ pip install blowfish\n \n`pip` can also install the latest development version directly from `git`::\n \n $ pip install 'git+https://github.com/jashandeep-sohi/python-blowfish.git'\n \n.. _pypi: https://pypi.python.org/pypi/blowfish\n\nDevelopment\n-----------\nWant to add a mode of operation? Speed up encryption?\n\nMake your changes to a clone of the repository at\nhttps://github.com/jashandeep-sohi/python-blowfish\nand send me a pull request.\n\nTests\n-----\nTests are written using the Python `unittest` framework. All tests are in the\n``test.py`` file and can be run using::\n \n $ python -m unittest test.py\n\n\nBugs\n----\nAre you having problems? Please let me know at\nhttps://github.com/jashandeep-sohi/python-blowfish/issues\n\nUsage\n-----\n.. warning::\n\n Cryptography is complex, so please don't use this module in anything\n *critical* without understanding what you are doing and checking the source\n code to make sure it is doing what you want it to.\n \n.. note::\n\n This is just a quick overview on how to use the module. For detailed\n documentation please see the `docstrings` in the module.\n\nFirst create a `Cipher` object with a `key`.\n\n.. code:: python3\n\n import blowfish\n \n cipher = blowfish.Cipher(b\"Key must be between 4 and 56 bytes long.\")\n \nBy default this initializes a Blowfish cipher that will interpret bytes using\nthe big-endian byte order. Should the need arrise to use the little-endian byte\norder, provide ``\"little\"`` as the second argument.\n\n.. code:: python3\n\n cipher_little = blowfish.Cipher(b\"my key\", byte_order = \"little\")\n \nBlock\n#####\nTo encrypt or decrypt a block of data (8 bytes), use the `encrypt_block` or\n`decrypt_block` methods of the `Cipher` object.\n\n.. code:: python3\n\n from os import urandom\n \n block = urandom(8)\n \n ciphertext = cipher.encrypt_block(block)\n plaintext = cipher.decrypt_block(ciphertext)\n \n assert block == plaintext\n \nAs these methods can only operate on 8 bytes of data, they're of little\npractical use. Instead, use one of the implemented modes of operation.\n \nElectronic Codebook Mode (ECB)\n##############################\nTo encrypt or decrypt data in ECB mode, use `encrypt_ecb` or `decrypt_ecb`\nmethods of the `Cipher` object. ECB mode can only operate on data that is a\nmultiple of the block-size in length.\n\n.. code:: python3\n\n data = urandom(10 * 8) # data to encrypt\n \n data_encrypted = b\"\".join(cipher.encrypt_ecb(data))\n data_decrypted = b\"\".join(cipher.decrypt_ecb(data_encrypted)\n \n assert data == data_decrypted\n \nElectronic Codebook Mode with Cipher Text Stealing (ECB-CTS)\n############################################################\nTo encrypt or decrypt data in ECB-CTS mode, use `encrypt_ecb_cts` or \n`decrypt_ebc_cts` methods of the `Cipher` object. ECB-CTS mode can operate\non data of any length greater than 8 bytes.\n\n.. code:: python3\n\n data = urandom(10 * 8 + 5) # data to encrypt\n \n data_encrypted = b\"\".join(cipher.encrypt_ecb_cts(data))\n data_decrypted = b\"\".join(cipher.decrypt_ecb_cts(data_encrypted))\n \n assert data == data_decrypted\n \nCipher-Block Chaining Mode (CBC)\n################################\nTo encrypt or decrypt data in CBC mode, use `encrypt_cbc` or `decrypt_cbc`\nmethods of the `Cipher` object. CBC mode can only operate on data that is a\nmultiple of the block-size in length.\n\n.. code:: python3\n\n data = urandom(10 * 8) # data to encrypt\n iv = urandom(8) # initialization vector\n \n data_encrypted = b\"\".join(cipher.encrypt_cbc(data, iv))\n data_decrypted = b\"\".join(cipher.decrypt_cbc(data_encrypted, iv))\n \n assert data == data_decrypted\n \nCipher-Block Chaining with Ciphertext Stealing (CBC-CTS)\n########################################################\nTo encrypt or decrypt data in CBC-CTS mode, use `encrypt_cbc_cts` or\n`decrypt_cbc_cts` methods of the `Cipher` object. CBC-CTS mode can operate\non data of any length greater than 8 bytes.\n\n.. code:: python3\n\n data = urandom(10 * 8 + 6) # data to encrypt\n iv = urandom(8) # initialization vector\n \n data_encrypted = b\"\".join(cipher.encrypt_cbc_cts(data, iv))\n data_decrypted = b\"\".join(cipher.decrypt_cbc_cts(data_encrypted, iv))\n \n assert data == data_decrypted\n\nPropagating Cipher-Block Chaining Mode (PCBC)\n#############################################\nTo encrypt or decrypt data in PCBC mode, use `encrypt_pcbc` or `decrypt_pcbc`\nmethods of the `Cipher` object. PCBC mode can only operate on data that is a\nmultiple of the block-size in length.\n\n.. code:: python3\n\n data = urandom(10 * 8) # data to encrypt\n iv = urandom(8) # initialization vector\n \n data_encrypted = b\"\".join(cipher.encrypt_pcbc(data, iv))\n data_decrypted = b\"\".join(cipher.decrypt_pcbc(data_encrypted, iv))\n \n assert data == data_decrypted\n\nCipher Feedback Mode (CFB)\n##########################\nTo encrypt or decrypt data in CFB mode, use `encrypt_cfb` or `decrypt_cfb`\nmethods of the `Cipher` object. CFB mode can operate on data of any length.\n\n.. code:: python3\n\n data = urandom(10 * 8 + 7) # data to encrypt\n iv = urandom(8) # initialization vector\n \n data_encrypted = b\"\".join(cipher.encrypt_cfb(data, iv))\n data_decrypted = b\"\".join(cipher.decrypt_cfb(data_encrypted, iv))\n \n assert data == data_decrypted\n\nOutput Feedback Mode (OFB)\n##########################\nTo encrypt or decrypt data in OFB mode, use `encrypt_ofb` or `decrypt_ofb`\nmethods of the `Cipher` object. OFB mode can operate on data of any length.\n\n.. code:: python3\n \n data = urandom(10 * 8 + 1) # data to encrypt\n iv = urandom(8) # initialization vector\n \n data_encrypted = b\"\".join(cipher.encrypt_ofb(data, iv))\n data_decrypted = b\"\".join(cipher.decrypt_ofb(data_encrypted, iv))\n \n assert data == data_decrypted\n\nCounter Mode (CTR)\n##################\nTo encrypt or decrypt data in CTR mode, use `encrypt_ctr` or `decrypt_ctr`\nmethods of the `Cipher` object. CTR mode can operate on data of any length.\nAlthough you can use any `counter` you want, a simple increment by one counter\nis secure and the most popular. So for convenience sake a simple increment by\none counter is implemented by the `blowfish.ctr_counter` function. However,\nyou should implement your own for optimization purposes.\n\n.. code:: python3\n\n from operator import xor\n \n data = urandom(10 * 8 + 2) # data to encrypt\n \n # increment by one counters\n nonce = int.from_bytes(urandom(8), \"big\")\n enc_counter = blowfish.ctr_counter(nonce, f = xor)\n dec_counter = blowfish.ctr_counter(nonce, f = xor)\n \n data_encrypted = b\"\".join(cipher.encrypt_ctr(data, enc_counter))\n data_decrypted = b\"\".join(cipher.decrypt_ctr(data_encrypted, dec_counter))\n \n assert data == data_decrypted\n\n.. vim: tabstop=2 expandtab",
"bugtrack_url": null,
"license": "GPLv3",
"summary": "Fast, efficient Blowfish cipher implementation in pure Python (3.4+).",
"version": "0.6.1",
"project_urls": {
"Download": "UNKNOWN",
"Homepage": "https://github.com/jashandeep-sohi/python-blowfish"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ca066008f79f3df714da4eeb6d7daf5e417e072c69923d22ede09171e74d69f8",
"md5": "47d9e27f4cd19632400875b19f1ad28f",
"sha256": "1626d96d2672a6cf021d9b66a5013b6e594865403b4a06d75034e0a9ff1cbdc6"
},
"downloads": -1,
"filename": "blowfish-0.6.1.tar.bz2",
"has_sig": false,
"md5_digest": "47d9e27f4cd19632400875b19f1ad28f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 27824,
"upload_time": "2015-02-28T23:38:39",
"upload_time_iso_8601": "2015-02-28T23:38:39.186413Z",
"url": "https://files.pythonhosted.org/packages/ca/06/6008f79f3df714da4eeb6d7daf5e417e072c69923d22ede09171e74d69f8/blowfish-0.6.1.tar.bz2",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a7a117edc0bd3557e7c942e1e145dc253b7262b0d24f10f8744ff57666ff0c19",
"md5": "e4239fcfc9f70062f6f670a7c59d6ea2",
"sha256": "a08c6a640ae39afab34dd73f7536a34fa318dfb4c281bc6cb246122210c1e176"
},
"downloads": -1,
"filename": "blowfish-0.6.1.tar.gz",
"has_sig": false,
"md5_digest": "e4239fcfc9f70062f6f670a7c59d6ea2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 32298,
"upload_time": "2015-02-28T23:38:36",
"upload_time_iso_8601": "2015-02-28T23:38:36.302305Z",
"url": "https://files.pythonhosted.org/packages/a7/a1/17edc0bd3557e7c942e1e145dc253b7262b0d24f10f8744ff57666ff0c19/blowfish-0.6.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2015-02-28 23:38:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jashandeep-sohi",
"github_project": "python-blowfish",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "blowfish"
}