Per Erik Strandberg /cv /kurser /blog

What is TXET?

TXET is the name of the encryption software I am building. I have a demo with minimal, but complete features on this page. Also I have a domain for it: www.txet.org [1]. The domain is so far linked to this page.

Can I use it?

Txet may be redistributed and/or modified under the terms of the Gnu General Public License. Download it in python here [2] . (This txet implementation in python is not compatible with the one below in M$-C#-format.)

If you are unable to deal with zip-files just copy paste from below. Please send me feedback on txet by clicking Kommentera/Comment at the bottom of this page, thank you and enjoy.

Example

Encrypting and decrypting Ubuntu 7.04 at 0.73 GB takes about 2 minutes on my computer.

>time txet -e -f ubuntu-7.04-desktop-i386.iso -q 
Password: 
Confirm:

real    2m8.927s
user    0m42.147s
sys     0m5.768s

>time txet -d -f ubuntu-7.04-desktop-i386.iso.txet
ubuntu-7.04-desktop-i386.iso.txet Password: 
ubuntu-7.04-desktop-i386.iso.txet: 731797504 of 731797504 decrypted (100.00 %)

real    2m11.807s
user    0m41.711s
sys     0m6.380s

Usage

For usage, just type 'txet --help'

Usage:    txet [-e|-d] [-q]? [-f infile -o outfile]+
          or
          txet [-e|-d] [-q]? [-f infile]+ (for default names)

Note:     default outnames are infilename + ".txet"

Examples: txet -e -f foo.tar.gz -o foo.tar.gz.txet
          foo.tar.gz is encrypted into foo.tar.gz.txet

          txet -d -f foo.tar.gz.txet -o foo.tar.gz
          foo.tar.gz.txet is decrypted into foo.tar.gz

          txet -e -f a.txt -o a.txet -f b.txt -o b.txet
          or
          txet -e -f a.txt -f b.txt -o a.txet -o b.txet
          encrypt a.txt into a.txet and b.txt into b.txet
          (the order of infiles (-f) and outfiles (-o)  matter -
          items are not paired)

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -e, --enc             Encrypt the files
  -d, --dec             Decrypt the files
  -f INFILE, -i INFILE, --file=INFILE
                        For multiple files, use -f once per file.
  -o OUTFILE, --out=OUTFILE
                        For multiple files, use -o once per file.
  -q, --quiet           Turn off display of information.

Requirements

To use txet you need Python. It works on 2.5 and probably a lot of other versions. Get python here: [3]

Source code

#!/usr/bin/python


# txet (text to txet) - Copyright (C) 2007 Per Erik Strandberg
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


# TODO/XXX list:
#     encrap the buffer used for reading infiles when encrypting
#     encrap the buffer used for writing outfiles when decrypting
#     any more buffer to encrap?
#     find harder encryption? At least figure out the classification of this one
#     not ask for password for every file (by switch)
#     encrap variable that holds key and iv
#     add try/catch where appropriate (file operations, imports, more?)
#     add "remove-all-infiles or even shred-all-infiles" swith
#     read from stdin and still prompt for password?
#     can imports be minimized? perhaps from cStringIO import StringIO)


# imports
import StringIO
import getpass
from optparse import OptionParser
from string import join, printable, ascii_letters
from Crypto.Hash import MD5, MD2
from Crypto.Cipher import AES
from random import choice
from os import stat
from sys import argv


def parse_txet_args():
    """Parse command line arguments and return them"""

    usage = """Usage:    %prog [-e|-d] [-q]? [-f infile -o outfile]+
          or
          %prog [-e|-d] [-q]? [-f infile]+ (for default names)

Note:     default outnames are infilename + ".txet"

Examples: %prog -e -f foo.tar.gz -o foo.tar.gz.txet
          foo.tar.gz is encrypted into foo.tar.gz.txet

          %prog -d -f foo.tar.gz.txet -o foo.tar.gz
          foo.tar.gz.txet is decrypted into foo.tar.gz

          %prog -e -f a.txt -o a.txet -f b.txt -o b.txet
          or
          %prog -e -f a.txt -f b.txt -o a.txet -o b.txet
          encrypt a.txt into a.txet and b.txt into b.txet
          (the order of infiles (-f) and outfiles (-o)  matter -
          items are not paired)"""

    parser = OptionParser(usage = usage, version="%prog 0.1")

    parser.add_option('-e', '--enc', dest='encrypt',
                      action="store_true", default=False,
                      help='Encrypt the files')

    parser.add_option('-d', '--dec', dest='decrypt',
                      action="store_true", default=False,
                      help='Decrypt the files')

    parser.add_option('-f', '-i', '--file', dest='infile', action='append',
                      help="For multiple files, use -f once per file.")

    parser.add_option('-o', '--out', dest='outfile', action='append',
                      help="For multiple files, use -o once per file.")

    parser.add_option('-q', '--quiet', dest='verbose', action='store_false',
                      default=True, help="Turn off display of information.")

    # do the parsing
    (options, args) = parser.parse_args()

    # check for bad input
    if options.outfile and len(options.infile) != len(options.outfile):
        parser.error("\nSome outfiles specified but"
                     " not all.\nin:  %s\nout: %s"
                     %(join(options.infile,', '), join(options.outfile, ', ')))
    elif options.encrypt and options.decrypt:
        parser.error("\nExactly one of -d and -e is required (both provided).")
    elif not options.encrypt and not options.decrypt:
        parser.error("\nExactly one of -d and -e is required (none provided).")
    elif len(args) != 0:
        parser.error("\nOrphan arguments '%s' - infile%s with forgotten -f?"
                 % (join(args,"', '"), (len(args) != 1) * "s"))

    return options
# end parse_txet_args


def encrap_buffer(buffy, n=10):
    """Stores crap in a buffer a number of times."""
    # let us hope we are at the end of buffy
    lenb = buffy.tell()

    for t in range(40):
        lenb += choice(range(10,20))
    
    for t in range(n):
        buffy.seek(0)
        for i in range(lenb):
            buffy.write(choice(ascii_letters))
# end encrap_buffer


def get_key_and_iv(prompt="", confirm=False):
    """Get key and initialization vector by prompting and hashing. Confirm
    typically used when encrypting files, and not used when decrypting."""
    
    if prompt=="":
        a = StringIO.StringIO(getpass.getpass())
    else:
        a = StringIO.StringIO(getpass.getpass(prompt=prompt))

    if confirm:
        b = StringIO.StringIO(getpass.getpass(prompt='Confirm:'))
        
        a.seek(0)
        b.seek(0)

        if a.read() != b.read():
            print "password mismatch - try again."
            return get_key_and_iv(prompt, confirm)

    # get key by MD5'ing the password
    a.seek(0)
    hasher = MD5.new()
    hasher.update(a.read())
    key = hasher.digest()

    # get iv by MD2'ing the password
    a.seek(0)
    iver = MD2.new()
    iver.update(a.read())
    iv = iver.digest()

    # put crap in buffer that previously had password
    encrap_buffer(a)
    encrap_buffer(a)
            
    return (key, iv)
# end get_key_and_iv


def get_cryptor(confirm=True):
    """Get new AES instance"""
    (key, iv) = get_key_and_iv(confirm=confirm)
    return AES.new(key, AES.MODE_CBC, iv)
# end get_cryptor


def txet(infiles, outfiles, verbose, entxet):
    """Encrypt or decrypt files in the list infiles. Output is stored in names
    provided in outfiles - if none are provided default names are used."""


    # global variables - for tweaking performance
    #
    # SIZE = bytes read each time (must be multiple of 16)
    #     small chunks require many reads (slow)
    #     very large chunks might bring performance problems
    #
    # INTERVAL = number of reads between each output on screen for user
    #     (output may be disabled by using the quiet switch)
    SIZE = 512
    INTERVAL = 199
    

    interval = INTERVAL
    total_seek = 0

    while infiles:
        item = infiles.pop(0)

        try:
            outfilename = outfiles.pop(0)
        except:
            if entxet:
                outfilename = item + ".txet"
            else:
                outfilename = item.replace('.txet','.bkp')                

        if verbose:
            print item + ' ',
        if entxet:
            cryptor = get_cryptor(True)
        else:
            cryptor = get_cryptor(False)
    
        i = file(item, 'r')
        o = file(outfilename, 'w')

        # write the size of the file in 32 bytes if encrypting
        # otherwise read the 32 bytes
        if entxet:
            insize = stat(item).st_size
            o.write('%032d' % insize)
        else:
            insize = int(i.read(32))

        size = SIZE
        seek = 0

        bytes = i.read(size)

        ctr = -1

        while len(bytes) == size: # always the case when detxeting
            seek += size

            if seek <= insize:
                if entxet:
                    o.write(cryptor.encrypt(bytes))
                else:
                    o.write(cryptor.decrypt(bytes))
            elif not entxet: # last write when decrypting
                o.write(cryptor.decrypt(bytes)[:insize%size])
            
            bytes = i.read(size)

            ctr += 1

            if verbose:
                if (ctr % interval) == 0:
                    print '\r%s: %d of %d %scrypted (%3.2f %%)' % (
                        item, seek, insize,
                        (1-entxet) * 'de' + entxet * 'en', 100.0*seek/insize
                        ),

        if len(bytes) != 0 and entxet: # last write when encrypting
            # pad with random printable char
            for n in range(size - len(bytes)):
                bytes += choice(printable)
        
            o.write(cryptor.encrypt(bytes))
            seek += len(bytes)
            
        seek = insize

        if verbose:
            print '\r%s: %d of %d %scrypted (%3.2f %%)' % (
                item, insize, insize, (1-entxet) * 'de' + entxet * 'en', 100.0
                )
    
        o.close()
        i.close()
        total_seek += insize

    return total_seek
# end detxet


# if called from command line (expected usage) then do it
if __name__ == "__main__":
    options = parse_txet_args()
    txet(options.infile, options.outfile, options.verbose, options.encrypt)
# end if


OLD VERSION FOR .NET HERE

TXET is the name of the encryption software I am building. I have a demo with minimal, but complete features on this page. Also I have a domain for it: www.txet.org [4]. The domain is so far linked to this page.

WARNING

It may be illegal for you to use TXET (see f.x. [5] or [6]). If you do the crime - you do the time. If you use TXET illegally then that is up to you - I take no responsibility what so ever for your crimes.

Also it may be illegal for you to download TXET into the country where you are. Also it might be illegal for you to send copies of TXET to anyone outside your country.

Please also read the license text below, follow the link, and read up on Creative Commons.

Example

First run Per Erik Strandberg's TXET from the console on all cs-files in the folder. Then look at the contents of the file and see junk. Decrypt and look at the decrypted contents.
http://www.pererikstrandberg.se/projects/txet/screenshot_txet.png

Download

Per Erik Strandbergs TXET can be downloaded in zipped format from here: [7] (you need the free of charge Microsoft .NET 2+ platform to run TXET, or if you prefer: the opensource MONO platform).

Licence

Per Erik Strandberg's TXET is licensed under a Creative Commons by-nc-nd 2.5 License, see [8].

Name

The name TXET (or txeT, or just txet) is of course an "encrypted" version of the word text. I will most likely invent a recursive acronym for txeT soon since I hate recursive acronyms.

See also

A little more is explained here: [9]

Features

TxeT uses:


This page belong in the category Kategori Mjukvara.