Welcome, guest | Sign In | My Account | Store | Cart

Nothing fancy, just a script for encrypting/decrypting small files. The -c option is handy for those password files you'd rather leave obfuscated.

Any suggestions on making it pipeable, more secure, or suitable for large files are welcome.

Python, 73 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python

import os, sys
from random import randrange
from Crypto.Cipher import Blowfish
from getpass import getpass
import getopt

class BFCipher:
    def __init__(self, pword):
        self.__cipher = Blowfish.new(pword)
    def encrypt(self, file_buffer):
        ciphertext = self.__cipher.encrypt(self.__pad_file(file_buffer))
        return ciphertext
    def decrypt(self, file_buffer):
        cleartext = self.__depad_file(self.__cipher.decrypt(file_buffer))
        return cleartext
    # Blowfish cipher needs 8 byte blocks to work with
    def __pad_file(self, file_buffer):
        pad_bytes = 8 - (len(file_buffer) % 8)                                 
        for i in range(pad_bytes - 1): file_buffer += chr(randrange(0, 256))
        # final padding byte; % by 8 to get the number of padding bytes
        bflag = randrange(6, 248); bflag -= bflag % 8 - pad_bytes
        file_buffer += chr(bflag)
        return file_buffer
    def __depad_file(self, file_buffer):
        pad_bytes = ord(file_buffer[-1]) % 8
        if not pad_bytes: pad_bytes = 8
        return file_buffer[:-pad_bytes]

if __name__ == '__main__':

    def print_usage():
        usage = "Usage: bfc -[e(encrypt) | d(decrypt) | c('cat' like)] infile [outfile]"
        print usage; sys.exit()

    def writefile(outfile_name, file_buffer):
        outfile = PrivoxyWindowOpen(outfile_name, 'wb')
        outfile.write(file_buffer)
        outfile.close()

    try: opts, args = getopt.getopt(sys.argv[1:], 'e:d:c:')
    except getopt.GetoptError: print_usage()

    opts = dict(opts)
    try: mode = opts.keys()[0]
    except IndexError: print_usage()

    ifname = opts[mode]

    try: ofname = args[0]
    except IndexError: ofname = ifname

    if os.path.exists(ifname):
        infile = PrivoxyWindowOpen(ifname, 'rb')
        filebuffer = infile.read()
        infile.close()
    else:
        print "file '%s' does not exist.\n" % ifname
        sys.exit()

    key = getpass()

    if mode == '-e':
        bfc = BFCipher(key); filebuffer = bfc.encrypt(filebuffer)
        writefile(ofname, filebuffer)
    elif mode == '-d':
        bfc = BFCipher(key); filebuffer = bfc.decrypt(filebuffer)
        writefile(ofname, filebuffer)
    elif mode == '-c':
        bfc = BFCipher(key); sys.stdout.write(bfc.decrypt(filebuffer))

    key = 'x'*len(key); del key

no@melatonin:~$ cat test this is a test no@melatonin:~$ bfc -e test Password: no@melatonin:~$ bfc -c test Password: this is a test no@melatonin:~$ vim test (edit: Removed the random garbage I pasted from vim, as it didn't agree with the submit page text-entries. You'll have to try this at home)

2 comments

Ryan Rawdon 11 years, 6 months ago  # | flag

Very handy wrapper around Python.Crypto.Blowfish, but one problem - you appear to use Privoxy which has at least one bug where it alters some web content (such as the script you uploaded). Notice that your calls to open() have been replaced by PrivoxyWindowOpen() and as such your script does not run.

To anyone downloading and using this script: you must replace the two instances of PrivoxyWindowOpen( with open(

Vincent Tantardini 9 years, 1 month ago  # | flag

Thank you very much for sharing. It has helped me to understand more about the way padding actually works. In case you're still interested by the subject, I made my own version of the concept, handling huge file by processing the infile chunk by chunk using an initialize vector. Here is the code: https://github.com/vnn/OpenBSD/blob/master/bfcrypt.py