This is a slightly modified version of the pure python implementation of the Blowfish cipher by Michael Gilfix. This version contains methods to encrypt and decrypt arbitrary strings (of arbitrary length) using the CTR cipher mode. I've added three new methods: initCTR(), encryptCTR() and decryptCTR() to make this happen. It also contains CBC code contributed by Joel Edwards.
Download Blowfish in Python module.
You might also be interested in XXTEA cipher in pure Python.
552 key = 'This is a test key' 553 cipher = Blowfish (key) 554 555 print "Testing encryption:" 556 xl = 123456 557 xr = 654321 558 print "\tPlain text: (%s, %s)" %(xl, xr) 559 cl, cr = cipher.cipher (xl, xr, cipher.ENCRYPT) 560 print "\tCrypted is: (%s, %s)" %(cl, cr) 561 dl, dr = cipher.cipher (cl, cr, cipher.DECRYPT) 562 print "\tUnencrypted is: (%s, %s)" %(dl, dr) 563 564 print "Testing block encrypt:" 565 text = 'testtest' 566 print "\tText:\t\t%s" %text 567 crypted = cipher.encrypt (text) 568 print "\tEncrypted:\t%s" %crypted 569 decrypted = cipher.decrypt (crypted) 570 print "\tDecrypted:\t%s" %decrypted 571 572 print "Testing CTR encrypt:" 573 cipher.initCTR() 574 text = "The quick brown fox jumps over the lazy dog" 575 print "\tText:\t\t", text 576 crypted = cipher.encryptCTR(text) 577 print "\tEncrypted:\t", crypted 578 cipher.initCTR() 579 decrypted = cipher.decryptCTR(crypted) 580 print "\tDecrypted:\t", decrypted
How secure is it? For one, Blowfish itself has never been broken, so from this point of view it is as secure as AES and other newer algorithms. Blowfish is used in many security products like OpenBSD's OpenSSH, OpenSSL and for the password databases of BSD and Linux systems because of its early implementation (it was created in 1993 by Bruce Scheiner). Since it was created so long ago, it is designed to be very efficient, and it's very fast on modern hardware. Of course, an implementation in Python cannot be as fast as an optimized implementation in C.
One way to completely avoid the problem with reusing the key in stream ciphers is to create a random number which is appended to the password but which is stored or transmitted without encryption before the encrypted part of the message. The other side can use the same number with the password to decrypt the protected message.
Update: The implementation now contains a test with some of the standard Blowfish test vectors, which it nominally passes. If by any chance your tests fail (the tests can be run by simply executing blowfish.py in Python), it most likely means that your Python is broken.