Fast, efficient Blowfish cipher implementation in pure Python (3.4+).

Overview

PyPI CI

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>.

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
  • 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
  • Electronic Codebook (ECB) mode
  • Electronic Codebook with Ciphertext Stealing (ECB-CTS) 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'

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 currently reside in the test.py file and can be run using the distutils script:

$ python setup.py test

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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
Comments
  • Bad Pi!

    Bad Pi!

    After using 'PI' sign in source, i can't install module via pip on Kubuntu/Pythin3.5, and QPython/Python3.5. When i remove 'PI' sign, importing of module works well. `

    import blowfish Traceback (most recent call last): File "", line 1, in File "blowfish.py", line 32 SyntaxError: Non-ASCII character '\xcf' in file blowfish.py on line 32, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

    `

    opened by Moneetor 3
  • Bytes to str and back, ctr_counter

    Bytes to str and back, ctr_counter

    Hoping you might be able to point me in the right direction.

    I'm using encrypt_ctr successfully, however the storage medium I'm using requires me to store into str. I'm not sure what encoding/decoding to use to make it go to a str, and then be able to be converted from str back to bytes for decrypt_ctr to handle.

    At the moment, decryption is sort of like:

    encryptedBytes = b"".join(encryptedBytesList)
    with open(metadata["filename"], "wb") as openFile:
                decoded_data = b"".join(self.cipher.decrypt_ctr(data, self.encrypt_counter))
                openFile.write(decoded_data)
    

    And encryption, sort of like:

    with open(os.path.expanduser("~/reddiSync/") + filename, "rb") as openFile:
                data = openFile.read()
                encoded_data = b"".join(self.cipher.encrypt_ctr(data, self.encrypt_counter))
            encoded_list = [encoded_data[i:i+1000] for i in range(0, len(data), 1000)]
            return [str(x) for x in encoded_list]
    

    Its ensuring the original conversion to str that's the issue.

    UTF-8 isn't compatible with some of the bytes produced, so is there an encoding I could use?

    opened by shakna-israel 2
  • DES_set_key_checked in blowfish

    DES_set_key_checked in blowfish

    I encountered a problem about DES_cfb64_encrypt, i use "cipher.encrypt_cfb(data, iv)" but incorrect result. i found that no similar function in cipher.

    opened by jmpews 2
  • Docs - electronic code book

    Docs - electronic code book

    One of the first items under "Usage" on the README is how to use ECB mode. I would like to suggest that this section should be accompanied by a warning that ECB mode is inherently insecure and does not provide strong secrecy. It is in fact very vulnerable to cryptanlysis and secrecy can be compromised even without side-channels.

    I would also recommend that this section not be placed first in the documentation.

    A set of images on wikipedia illustrates dramatically the way ECB mode leaks data: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#ECB

    opened by leifurhauks 1
  • Add a 'test' command to setup.py to run unittests

    Add a 'test' command to setup.py to run unittests

    Now tests can be run using the distutils script:

    $ python setup.py test -vv
    running test
    running build_py
    test_decrypt_block (test.Cipher) ... ok
    test_encrypt_block (test.Cipher) ... ok
    test_decrypt_block (test.CipherLittleEndian) ... ok
    test_encrypt_block (test.CipherLittleEndian) ... ok
    test_cbc_cts_mode (test.ModesOfOperation) ... ok
    test_cbc_mode (test.ModesOfOperation) ... ok
    test_cfb_mode (test.ModesOfOperation) ... ok
    test_ctr_mode (test.ModesOfOperation) ... ok
    test_ecb_cts_mode (test.ModesOfOperation) ... ok
    test_ecb_mode (test.ModesOfOperation) ... ok
    test_ofb_mode (test.ModesOfOperation) ... ok
    test_pcbc_mode (test.ModesOfOperation) ... ok
    
    ----------------------------------------------------------------------
    Ran 12 tests in 1.816s
    
    OK
    
    enhancement 
    opened by jashandeep-sohi 0
  • Fix little-endian byte-order input encryption and decryption.

    Fix little-endian byte-order input encryption and decryption.

    This fixes bug https://github.com/jashandeep-sohi/python-blowfish/issues/9.

    u4_1_struct is used to split 32-bit integers into 4 bytes. The higher 8 bits should be the first byte, the next 8 bits should be the next byte, and so on. So, it should always be in big-endian byte order and not be dependent on the byte_order option.

    opened by jashandeep-sohi 0
  • Add custom exceptions for incorrect input data

    Add custom exceptions for incorrect input data

    Currently, the generic struct.error is raised when the input data is not the correct length. Raise a custom exception so it's a bit more clear as to why the call failed.

    enhancement 
    opened by jashandeep-sohi 0
  • Need example for encrypt/decrypt for a large file (say 1mb)

    Need example for encrypt/decrypt for a large file (say 1mb)

    Hello there this is just awesome. However, I am in a hurry and looing for a sample code which encrypts and decrypts a big file what is the cost of encryption? is it O(n) ? thanks Sriram

    opened by sriramb12 0
A tutorial for people to run synthetic data replica's from source healthcare datasets

Synthetic-Data-Replica-for-Healthcare Description What is this? A tailored hands-on tutorial showing how to use Python to create synthetic data replic

11 Mar 22, 2022
Near Zero-Overhead Python Code Coverage

Slipcover: Near Zero-Overhead Python Code Coverage by Juan Altmayer Pizzorno and Emery Berger at UMass Amherst's PLASMA lab. About Slipcover Slipcover

PLASMA @ UMass 325 Dec 28, 2022
Watch a Sphinx directory and rebuild the documentation when a change is detected. Also includes a livereload enabled web server.

sphinx-autobuild Rebuild Sphinx documentation on changes, with live-reload in the browser. Installation sphinx-autobuild is available on PyPI. It can

Executable Books 440 Jan 06, 2023
Yet Another MkDocs Parser

yamp Motivation You want to document your project. You make an effort and write docstrings. You try Sphinx. You think it sucks and it's slow -- I did.

Max Halford 10 May 20, 2022
layout-parser 3.4k Dec 30, 2022
Simple yet powerful CAD (Computer Aided Design) library, written with Python.

Py-MADCAD it's time to throw parametric softwares out ! Simple yet powerful CAD (Computer Aided Design) library, written with Python. Installation

jimy byerley 124 Jan 06, 2023
SCTYMN is a GitHub repository that includes some simple scripts(currently only python scripts) that can be useful.

Simple Codes That You Might Need SCTYMN is a GitHub repository that includes some simple scripts(currently only python scripts) that can be useful. In

CodeWriter21 2 Jan 21, 2022
Documentation of the QR code found on new Austrian ID cards.

Austrian ID Card QR Code This document aims to be a complete documentation of the format used in the QR area on the back of new Austrian ID cards (Per

Gabriel Huber 9 Dec 12, 2022
NoVmpy - NoVmpy with python

git clone -b dev-1 https://github.com/wallds/VTIL-Python.git cd VTIL-Python py s

263 Dec 23, 2022
Anomaly Detection via Reverse Distillation from One-Class Embedding

Anomaly Detection via Reverse Distillation from One-Class Embedding Implementation (Official Code ⭐️ ⭐️ ⭐️ ) Environment pytorch == 1.91 torchvision =

73 Dec 19, 2022
Version bêta d'un système pour suivre les prix des livres chez Books to Scrape,

Version bêta d'un système pour suivre les prix des livres chez Books to Scrape, un revendeur de livres en ligne. En pratique, dans cette version bêta, le programme n'effectuera pas une véritable surv

Mouhamed Dia 1 Jan 06, 2022
Documentation for GitHub Copilot

NOTE: GitHub Copilot discussions have moved to the Copilot Feedback forum. GitHub Copilot Welcome to the GitHub Copilot user community! In this reposi

GitHub 21.3k Dec 28, 2022
Project documentation with Markdown.

MkDocs Project documentation with Markdown. View the MkDocs documentation. Project release notes. Visit the MkDocs wiki for community resources, inclu

MkDocs 15.6k Jan 02, 2023
This is the data scrapped of all the pitches made up potential startup's to established bussiness tycoons of India with all the details of Investments made, equity share, Name of investor etc.

SharkTankInvestor This is the data scrapped of all the pitches made up potential startup's to established bussiness tycoons of India with all the deta

Subradip Poddar 2 Aug 02, 2022
freeCodeCamp Scientific Computing with Python Project for Certification.

Polygon_Area_Calculator freeCodeCamp Python Project freeCodeCamp Scientific Computing with Python Project for Certification. In this project you will

Rajdeep Mondal 1 Dec 23, 2021
A complete kickstart devcontainer repository for python3

A complete kickstart devcontainer repository for python3

Viktor Freiman 3 Dec 23, 2022
Obmovies - A short guide on setting up the system and environment dependencies required for ob's Movies database

Obmovies - A short guide on setting up the system and environment dependencies required for ob's Movies database

1 Jan 04, 2022
EasyModerationKit is an open-source framework designed to moderate and filter inappropriate content.

EasyModerationKit is a public transparency statement. It declares any repositories and legalities used in the EasyModeration system. It allows for implementing EasyModeration into an advanced charact

Aarav 1 Jan 16, 2022
Plugins for MkDocs.

Plugins for MkDocs and Python Markdown pip install neoteroi-mkdocs This package includes the following plugins and extensions: Name Description Type m

35 Dec 23, 2022
Minimal reproducible example for `mkdocstrings` Python handler issue

Minimal reproducible example for `mkdocstrings` Python handler issue

Hayden Richards 0 Feb 17, 2022