Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

CryptoPad

by sifukurt (Hermit)
on Dec 28, 2001 at 23:49 UTC ( #134949=sourcecode: print w/ replies, xml ) Need Help??

Category: Cryptography
Author/Contact Info Kurt Kincaid (sifukurt@yahoo.com)
Description: This script started off as one of those "I wonder if I can do this" sort of things. I wanted to get more proficient at using Tk, and I really just did it for the challenge and for the fun. I can't make any claims as to the overall level of security it provides. If you use it insecurely, it'll be insecure, simple as that. It does require several modules, all of which are listed at the top of the script. I really only designed it with mild security in mind, so if you use it for matters of national security, you do so at your own risk.

Hopefully you'll find it at least somewhat useful.

UPDATE: The problem with the zero length file output (detailed below) was a very careless error on my part. I apologize for any inconvenience this may have caused. I have corrected the error in the code contained herein.
#--------------------------------------------------------------------#
# CryptoPad
#       Date Written:   07-Nov-2001 09:29:47 AM
#       Last Modified:  28-Dec-2001 12:30:23 PM
#       Author:    Kurt Kincaid (sifukurt@yahoo.com)
#       Copyright (c) 2001, Kurt Kincaid
#           All Rights Reserved
#
# NOTICE: This package is free software and may be modified and/or
#         redistributed under the same terms as Perl itself.
#--------------------------------------------------------------------#

use Tk;
use Tk::Dialog;
use Tk::DialogBox;
use Tk::Text;
use Tk::FileSelect;
use Tk::FileDialog;
use Tk::Menu;
use Tk::Menubutton;
use Tk::widgets qw(Menu);
use Tk::Checkbutton;
use File::Butler;
use File::Glob;
use Crypt::RC4;
use Crypt::GOST_PP;
use Crypt::TripleDES;
use Crypt::CBC;
use Crypt::Rijndael_PP ':all';
use Crypt::RIPEMD160;
use Crypt::PPDES;
use URI::Escape;
use Digest::MD2;
use Digest::MD4;
use Digest::MD5;
use Digest::SHA1;
use constant;

$VERSION          = "1.31";
$mod_date         = "28-Dec-2001 12:30:23 PM";
$title            = "CryptoPad v" . $VERSION;
$rc4_header       = "----- CryptoPad RC4 Encrypted Message: Begin ----
+-\n";
$rc4_footer       = "\n----- CryptoPad RC4 Encrypted Message: End ----
+-";
$tripledes_header = "----- CryptoPad TripleDES Encrypted Message: Begi
+n -----\n";
$tripledes_footer = "\n----- CryptoPad TripleDES Encrypted Message: En
+d -----";
$aes_header       = "----- CryptoPad AES (Rijndael) Encrypted Message:
+ Begin -----\n";
$aes_footer       = "\n----- CryptoPad AES (Rijndael) Encrypted Messag
+e: End -----";
$gost_header      = "----- CryptoPad GOST Encrypted Message: Begin ---
+--\n";
$gost_footer      = "\n----- CryptoPad GOST Encrypted Message: End ---
+--";

$mw    = MainWindow->new;
$mw->title($title);

$m = $mw->Frame( -relief => 'groove', -bd => 2 )
  ->pack( -side => 'top', -anchor => 'n', -fill => 'x' );

$m->Menubutton(
    -text      => "File",
    -tearoff   => 0,
    -menuitems => [
        [
            "command" => "New",
            -command  => \&clear
        ],
        [
            "command" => "Open",
            -command  => \&OpenDocument
        ],
        [
            "command" => "Save",
            -command  => \&SaveDocument
        ],
        [
            "command" => "Save As",
            -command  => \&SaveAs
        ],
        [
            "command" => "Exit",
            -command => sub { exit }
        ]
    ]
)->pack( -side => 'left' );

$m->Menubutton(
    -text      => "Help",
    -tearoff   => 0,
    -menuitems => [
        [
            "command" => "Help...",
            -command  => \&help
        ],
        [
            "command" => "About...",
            -command  => \&about
        ]
    ]
)->pack( -side => 'left' );

$f = $mw->Frame->pack( -side => 'top', -fill => 'x' );
$f->Label( -text => "Passphrase:" )->pack( -side => 'left', -anchor =>
+ 'w' );
$f->Entry( -show => '*', -textvariable => \$passphrase )->pack(
    -side   => 'left',
    -anchor => 'w',
    -fill   => 'x',
    -expand => 1
);

$f->Button( -text => "Message Digest", -command => \&Digest )
  ->pack( -side => 'right' );
$f->Button( -text => "RC4 Decrypt", -command => \&rc4_decrypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "RC4 Encrypt", -command => \&rc4_encrypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "GOST Decrypt", -command => \&gost_decrypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "GOST Encrypt", -command => \&gost_encrypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "TripleDES Decrypt", -command => \&tripledes_decr
+ypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "TripleDES Encrypt", -command => \&tripledes_encr
+ypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "AES Decrypt", -command => \&aes_decrypt )
  ->pack( -side => 'right', -anchor => 'e' );
$f->Button( -text => "AES Encrypt", -command => \&aes_encrypt )
  ->pack( -side => 'right', -anchor => 'e' );


$f->Button( -text => "Clear", -command => \&clear )
  ->pack( -side => 'right', -anchor => 'e' );

$mw->Label( -textvariable => \$info, -relief => 'ridge' )
  ->pack( -side => 'bottom', -fill => 'x' );
$t = $mw->Scrolled("Text", -wrap => 'word', -scrollbars => 'e' )->pack
+(
    -side   => 'bottom',
    -fill   => 'both',
    -expand => 1
);

$info = $title;

MainLoop;

#--------------------------------------------------------------------#
# Encryption Sub-Routines
#--------------------------------------------------------------------#

sub rc4_encrypt {
    $info = "Processing....";
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        $cipher = RC4( $passphrase, $temp_var );
        $info = "";
        $t->delete( "1.0", "end" );
        $cipher = uri_escape($cipher);
        $cipher =~ s/.{80}/$&\n/g;
        chomp $cipher;
        $cipher = $rc4_header . $cipher . $rc4_footer;
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub rc4_decrypt {
    $info = "Processing....";
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        $temp_var =~ s/$rc4_header//;
        $temp_var =~ s/$rc4_footer//;
        $temp_var =~ s/\n//g;
        $temp_var = uri_unescape( $temp_var );
        $cipher = RC4( $passphrase, $temp_var );
        chomp $cipher;
        $info = "";
        $t->delete( "1.0", "end" );
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub tripledes_encrypt {
    $info = "Processing....";
    my $des = new Crypt::TripleDES;
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        $cipher = $des->encrypt3( $temp_var, $passphrase );
        $info = "";
        $t->delete( "1.0", "end" );
        $cipher = uri_escape($cipher);
        $cipher =~ s/.{80}/$&\n/g;
        chomp $cipher;
        $cipher = $tripledes_header . $cipher . $tripledes_footer;
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub tripledes_decrypt {
    $info = "Processing....";
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        my $des = new Crypt::TripleDES;
        $temp_var =~ s/$tripledes_header//;
        $temp_var =~ s/$tripledes_footer//;
        $temp_var =~ s/\n//g;
        $temp_var = uri_unescape( $temp_var );
        $cipher = $des->decrypt3( $temp_var, $passphrase );
        $cipher =~ s/\s*$//;
        chomp $cipher;
        $t->delete( "1.0", "end" );
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub aes_encrypt {
    $info = "Processing....";
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        $aes = new Crypt::CBC($passphrase,'Rijndael_PP');
        $cipher = $aes->encrypt( $temp_var );
        $info = "";
        $t->delete( "1.0", "end" );
        $cipher = uri_escape($cipher);
        $cipher =~ s/.{80}/$&\n/g;
        chomp $cipher;
        $cipher = $aes_header . $cipher . $aes_footer;
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub aes_decrypt {
    $info = "Processing....";
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        @lines = split(/\n/,$temp_var );
        shift @lines;
        pop @lines;
        $temp_var = join( "", @lines );
        $temp_var = uri_unescape( $temp_var );
        $aes = new Crypt::CBC($passphrase,'Rijndael_PP');
        $cipher = $aes->decrypt( $temp_var );
        chomp $cipher;
        $info = "";
        $t->delete( "1.0", "end" );
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub gost_encrypt {
    $info = "Processing....";
    my $ref = Crypt::GOST_PP->new( $passphrase );
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        $cipher = $ref->encrypt( $temp_var );
        $info = "";
        $t->delete( "1.0", "end" );
        $cipher = uri_escape($cipher);
        $cipher =~ s/.{80}/$&\n/g;
        chomp $cipher;
        $cipher = $gost_header . $cipher . $gost_footer;
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

sub gost_decrypt {
    $info = "Processing....";
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( Confirm() ) {
        my $ref = Crypt::GOST_PP->new( $passphrase );
        $temp_var =~ s/$gost_header//;
        $temp_var =~ s/$gost_footer//;
        $temp_var =~ s/\n//g;
        $temp_var = uri_unescape( $temp_var );
        $cipher = $ref->decrypt( $temp_var );
        $cipher =~ s/\s*$//;
        chomp $cipher;
        $t->delete( "1.0", "end" );
        $t->insert( "end", $cipher );
        $info = $title;
    }
}

#--------------------------------------------------------------------#
# End Encryption Sub-Routines
#--------------------------------------------------------------------#

sub clear {
    $t->delete( "1.0", "end" );
    $passphrase = "";
    $info       = $title;
}

sub about {
    $mw->Dialog( -title => "About...",
        -text => <<"END", -popover => $mw, -font => 'ansi' )->Show;
$title

Last Modified: $mod_date

Copyright  2001 Kurt Kincaid. All rights reserved.

This package is free software; you can redistribute it and/or modify i
+t under the same terms as Perl itself.
END
}

sub Digest {
    $info = "Generating Message Digest....";
    $hex  = Digest::MD5->new();
    $temp_var = $t->get( "1.0", "end" );
    chomp $temp_var;
    if ( $temp_var eq "" ) {
        $info = $title;
        return;
    }
    $hex->add( $temp_var );
    $md5  = $hex->hexdigest();
    $hex2 = Digest::SHA1->new();
    $hex2->add( $temp_var );
    $sha  = $hex2->hexdigest();
    $hex3 = Digest::MD4->new();
    $hex3->add( $temp_var );
    $md4  = $hex3->hexdigest();
    $hex4 = Digest::MD2->new();
    $hex4->add( $temp_var );
    $md2 = $hex4->hexdigest();
    $hex5 = Crypt::RIPEMD160->new();
    $hex5->reset();
    $hex5->add( $temp_var );
    $ripemd = $hex5->hexdigest();
    $mw->Dialog(
        -title => "Message Digest",
        -text  => <<"END", -popover => $mw, -font => 'ansi' )->Show;
[ SHA ]
$sha

[ MD5 ]
$md5

[ MD4 ]
$md4

[ MD2 ]
$md2

[ RIPEMD-160 ]
$ripemd
    
END
    $info = $title;
}

sub OpenDocument {
    $FSref    = $mw->FileSelect();
    $fileName = $FSref->Show();
    $temp_var     = Butler( $fileName, "read" );
    if ( !-e $fileName ) {
        $info = "Cannot open $fileName: $!";
        return;
    }
    $t->delete( "1.0", "end" );
    $t->insert( "end", $temp_var );
}

sub SaveDocument {
    if ( $fileName eq "" ) {
        $saveas = $mw->FileDialog( -Title => 'Save As', -Create => 1 )
+;
        $saveas->Label( -text  => "File Name: ", -relief       => 'gro
+ove' );
        $saveas->Entry( -width => 20,            -textvariable => \$fi
+leName );
        $fname = $saveas->Show();
    }
    $saveas->destroy();
    $temp_var[0] = $t->get( "1.0", "end" );
    Butler( $fname, "write", \@temp_var );
    $info = "$fname saved";
}

sub SaveAs {
    undef $fileName;
    SaveDocument();
}

sub help {
    $helptext = "
$title
    
Last Modified: $mod_date

The encryption is accomplished with your choice of several encryption 
+algorithms, TripleDES (the previous, interim NIST Data Encryption Sta
+ndard), AES (also known as Advanced Encryption Standard, or Rijndael,
+ after the authors, Vincent Rijmen and Joan Daemen, the current NIST 
+Data Encryption Standard), GOST (a 64-bit block cipher with a 256-bit
+ key, which was the encryption standard in the former Soviet Union) a
+nd RC4, which is a symmetrical stream cipher by RSA Security Inc. It 
+should be noted that to avoid complications with displaying meta-char
+acters, the encyrpted output is escaped via URI::Escape.

CryptoPad supports multiple rounds of encryption. For example, it is p
+ossible to encrypt your data with TripleDES, then with AES, then with
+ RC4. Decryption would then be possible in the reverse order. The nam
+e of the encryption algorithm is shown to facilitate this. It is impo
+rtant to note that knowing which encryption algorithm was used in no 
+way diminishes the security of the encryption.

The Message Digests are generated with SHA1, MD5, MD4, and MD2 Message
+ Digest algorithms by RSA Security Inc., and RIPEMD-160 by Hans Dobbe
+rtin, Antoon Bosselaers, and Bart Preneel, of Katholieke Universiteit
+ Leuven. A Message Digest (also known as \"fingerprint\") is a one-wa
+y encrypted hash function based on the content of the document. It is
+ mathematically infeasible to have two documents with the same Messag
+e Digest, and even less likely that the document would say what you w
+ant it to say. As such, a Message Digest can be used to \"sign\" a do
+cument and verify that the contents of the document have not been alt
+ered, either by accident or design.
";

    $help_label = "$title Help";
    $help = MainWindow->new();
    $help->title( "Help" );
    $mm = $help->Frame->pack( -side => 'top', -fill => 'x' );
    $mm->Button( -text => "Close Window", -command => sub { $help->des
+troy() } )
      ->pack( -side => 'right' );
    $help->Label(-textvariable => \$help_label, -relief => 'ridge')->p
+ack(-side => 'bottom', -fill => 'x');
    $tt = $help->Scrolled("Text", -width => 120, -wrap => 'word', -bac
+kground => '#ffff88', -font => 'ansi', -scrollbars => 'e' )
      ->pack(-side => 'bottom', -fill => 'both', -expand => 1 );
    $tt->insert( "end", $helptext );    
}

sub Confirm {
    if ( $temp_var eq "" ) {
        return 0;
    }
    if ( length( $passphrase ) < 5 ) {
        Error();
        return 0;
    }
    return 1;
}

sub Error {
    my $error;
    $error = $mw->Dialog( -bitmap => 'error', -title => "Passphrase Er
+ror",
        -text => <<"END", -popover => $mw, -font => 'ansi' )->Show;
The passphrase must be at least 5 characters.
END
    $info = $title;
}

Comment on CryptoPad
Download Code
Re: CryptoPad
by Beatnik (Parson) on Dec 29, 2001 at 22:29 UTC
    To optimize your code a bit and make it a bit more flexible, may I suggest using Crypt::CBC which simply takes a parameter to the required Cipher and handles it from there.

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
Re: CryptoPad
by zentara (Archbishop) on Jan 02, 2002 at 04:45 UTC
    I tried to run your script. It encrypts, but dosn't save the encrypted file(actually it saves a "0" length file). I also had to edit the button captions, to shorten them down, else the AES buttons get squashed off of the menus. I like the basic operation though.
      What sort of system are you running on? I've run it on both Win98 and WinXP and haven't run into the problem you're encountering w/ the zero-length file.

      With regard to the button captions, I designed CryptoPad on a machine running at 1280x1024 resolution, but I believe everything should look ok at 1024x768 as well. Anything less than that and, yes, I'm sure the buttons do get cropped. I've been toying with the idea of having the encryption options as part of a drop-down menu to solve this problem.
      ___________________
      Kurt

      I also had the zero length file problem when I ran it. I tried it on both of my linux boxes (debian:woody and RH:6.2). Both boxes use perl 5.6.1.

      I think the problem is in the line:

      Butler( $fname, "write", \@kurt );

      I am not familiar with File::Butler enough to know what it is doing. I had to load it to run CryptPad. However, I don't see another reference to kurt...except the author's name<G>.

      chuck

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://134949]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2014-10-23 02:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (123 votes), past polls