Blowfish Tk Client

snichols Below is some Tcl/Tk code for demonstrating how Tcl's blowfish encryption algorythm works. This TK app uses a plain text key field and plain text data field to create an encrypted blowfish data field. This app also allows you to save and load the data fields from file, and could give a basic demonstation on how to write a basic Tk form that asks the user for input from some entry fields, combo box, and command buttons.

Tcl Blowfish caveats I have found through testing:

- If the plain text data field is not divisible by 8 then extra characters are added to the decoded data field when it is decrypted.

- Decoding a plain text data field will actually encrypt it.

- Encrypting an blowfish encoded field will actually decode it.

- Security is based on the plain text field key size. The bigger the key size the better the encryption.

- When saving/opening files the file translation needs to be binary.

        package require Tk
        package require BWidget
        package require blowfish
        # Create the window
        proc BlowfishTool {} {
                global data key mode
                set mode cbc
                . configure -borderwidth 1
                set ::key SECRET
                set ::data ""
                wm protocol . WM_DELETE_WINDOW {exit}
                wm title . "Blowfish Encryption/Decipher Tool"
                wm resizable . 1 0
                label  .k -text "Key:" -anchor w
                entry  .key -show * -textvar ::key -highlightcolor yellow -highlightthickness 3
                label  .d -text "Data:" -anchor w
                entry  .data -textvar ::data -highlightcolor yellow -highlightthickness 3
                label  .m -text "Mode:" -anchor w
                ComboBox .mode -values {cbc ecb} \
                -modifycmd [list ComboUpdate .mode] \
                -autocomplete true \
                -editable false
                .mode setvalue @0        
                button .browser -text Load -command {LoadFile [tk_getOpenFile -filetypes {{"Data File"    {.key} }}]} -background red -foreground white
                button .e -text "Encrypt Data" -command {Encrypt} -foreground red
                button .de -text "Decipher Data" -command {Decrypt} -foreground blue -background white
                button .cancel -text Exit -command {exit} -background white -foreground red
                grid   .k .key - - -sticky news
                grid   .d .data - - -sticky news
                grid   .m .mode  - - -sticky news
                grid   .e .de - - -sticky news
                grid   .browser  - - -sticky news
                grid   .cancel - - -sticky news
                grid rowconfigure . 0 -weight 1
                grid columnconfigure . 1 -weight 1
                raise .
                grab set .
                focus .data
                vwait ::data
                button .save -text "Save" -command {SaveFile} -background blue
                grid   .save -  -  -sticky news
        # Event Driven. Called when the mode combobox is clicked.
        proc ComboUpdate {p} {
                global mode
                puts "ComboBox change: [$p cget -text]"
                set mode [$p cget -text]
        # Encode the data
        proc Encrypt { } {
                global data mode key
                set data [blowfish::blowfish -mode $mode -dir encrypt -key $key $data]
        # Decode the Encrypted data
        proc Decrypt { } {
                global data mode key
                set data [blowfish::blowfish -mode $mode -dir decrypt -key $key $data]
        # Save the data field.
        proc SaveFile { } {
                global data
                set types {
                        {"Data Files"       {.key} }
                set file [tk_getSaveFile -filetypes $types -defaultextension .key]
                # Only save the file if the user click save not cancel
                if {! [string match "" $file ]} {
                        set fileid [open $file w]
                        fconfigure $fileid -translation binary
                        puts $fileid $data
                        close $fileid  
        # Load the data field
        proc LoadFile {file} {
                global data mode
                if {[string match "" $file]} {return}
                set fileid [open $file r]
                fconfigure $fileid -translation binary
                set data [read $fileid]
                close $fileid
        # show background errors
        proc bgerror {value} {puts $value}
        # Call the main window

FYI...The Tcl Blowfish package used in the above sources can be found in TclLib or newer. Any comments you have regarding the above Tcl/Tk code are welcome. Thanks snichols.