30 April 1999


Date: Thu, 29 Apr 1999 13:48:28 -0700
From: "J. Orlin Grabbe" <kalliste@aci.net>
To: "cryptography@c2.net" <cryptography@c2.net>
Subject: Triple-DES with the Cryptix class library

I have found the Cryptix class library works fine for
3DES and other encryptions.  It's a little slow.

Here are two java programs I wrote which illustrate
how 3DES works using the Cryptix class library.

The first program encrypts a string (in the program)
using a key (in the program), and prints the string,
the key, and the encrypted string out to a text file
("DES-EDE3.out").  Sample output is shown following
the program listing.

The second program generates its own 3DES key, prints
this out to a textfile ("DES-EDE3.out"), reads in a
plaintext file (passed as an argument to main()),
encrypts the plaintext file with the key, and writes
the ciphertext to a ciphertext file.  Then, to check
the process, it deciphers the ciphertext bytes that
are still in memory and writes these out to to the
textfile.  Next, it reads in the ciphertext file,
decrypts the ciphertext, and also writes the decrypted
bytes to the textfile.  Sample output is shown also.

Orlin Grabbe

http://www.aci.net/kalliste/homepage.html


/*********************test2x3DES.java***************/

/********************************************/
/* test2x3DES.java takes a 3DES key input   */
/* and a text string from the program,      */
/* encrypts the string, and writes the key  */
/* the plaintext string, and the encrypted  */
/* result to a file DES-3EDE3.out           */
/* If cipher block chaining (CBC) is used   */
/* instead of ECB, an intilization vector   */
/* must be set first (lines not included).  */
/* --Orlin Grabbe                           */
/********************************************/

import java.io.*;
import java.security.*;
import java.math.*;
import cryptix.util.core.BI;
import cryptix.util.core.ArrayUtil;
import cryptix.util.core.Hex;
import cryptix.provider.key.*;


class test2x3DES {

public static void main (String[] args) {

try {
FileOutputStream outFile1 = new FileOutputStream("DES-
EDE3.out");
// Note: PrintStream is deprecated, but still works fine in
jdk1.1.7b
PrintStream output1 = new PrintStream(outFile1);

RawSecretKey key2 = new RawSecretKey("DES-
EDE3",Hex.fromString("3812A419C63BE771AD9F61FEFA20CE633812A419C63
BE771"));
//Use the following line instead for DES encryption
//RawSecretKey key2 = new
RawSecretKey("DES",Hex.fromString("3812A419C63BE771"));
RawKey rkey = (RawKey) key2;
byte[] yval = rkey.getEncoded();
BigInteger Bkey = new BigInteger(yval);
String w = cryptix.util.core.BI.dumpString(Bkey);
output1.println("The Encryption Key = " + w);
Cipher des=Cipher.getInstance("DES-
EDE3/ECB/NONE","Cryptix");
//Use the following line instead for DES encryption
//Cipher des=Cipher.getInstance("DES/ECB/NONE","Cryptix");
des.initEncrypt(key2);

byte[] ciphertext =
des.crypt(Hex.fromString("01010101010101010102030405060708090A0B0
C0D0E0F101112131415161718"));

/* print out length and representation of ciphertext */
output1.print("\n");
output1.println("ciphertext.length = " +
ciphertext.length);

BigInteger Bciph = new BigInteger(ciphertext);
w = cryptix.util.core.BI.dumpString(Bciph);
output1.println("Ciphertext for simple encryption = " + w);


/* decrypt ciphertext */
des.initDecrypt(key2);
ciphertext = des.crypt(ciphertext);
output1.print("\n");
output1.println("plaintext.length = " + ciphertext.length);

/* print out representation of decrypted ciphertext */
Bciph = new BigInteger(ciphertext);
w = cryptix.util.core.BI.dumpString(Bciph);
output1.println("Plaintext for simple encryption = " + w);

output1.println(" ");

output1.close();

      } catch (Exception e) {
            System.err.println("Caught exception " +
e.toString());
      }

}}
/********************end of test2x3DES.java******************/


/******************sample output from test2xDES.java**********/

The Encryption Key = Multi-Precision Integer 190 bits long...
sign: Positive
magnitude: 3812A419C63BE771 AD9F61FEFA20CE63 3812A419C63BE771

ciphertext.length = 32

Ciphertext for simple encryption = Multi-Precision Integer 255
bits long...
sign: Positive
magnitude: 741038365B8C4BC2 01B45F3A1C9C703E 5DE9007B2288BDBD
5203FEB4F80C5BD0

plaintext.length = 32
Plaintext for simple encryption = Multi-Precision Integer 249
bits long...
sign: Positive
magnitude: 0101010101010101 0102030405060708 090A0B0C0D0E0F10
1112131415161718
/***************end of sample output test2x3DES.java*************/


/**********************testx3DES.java************************/

/********************************************/
/* testx3DES generates its own 3DES key     */
/* then reads in a plaintext file, encrypts */
/* the plaintext file, writes the encrypted */
/* bytes out to a ciphertext file.  Next it */
/* decrypts the ciphertext bytes which are  */
/* still in memory, and writes these to the */
/* general output file.  Next it reads in   */
/* the ciphertext file, decrypts it and     */
/* writes this to the general output file.  */
/* If CBC is used instead of ECB, lines to  */
/* set an initialized vector will have to   */
/* be set.                                  */
/* --Orlin Grabbe                           */
/*------------------------------------------*/

import java.io.*;
import java.security.*;
import java.math.*;
import cryptix.util.core.BI;
import cryptix.util.core.ArrayUtil;
import cryptix.util.core.Hex;
import cryptix.provider.key.*;


class testx3DES {

public static void main (String[] args) {

try {
FileOutputStream outFile1 = new FileOutputStream("DES-
EDE3.out");
FileOutputStream outFile2 = new
FileOutputStream("DES3CIPH.out");
//PrintStream is deprecated, but works fine in jdk1.1.7b
PrintStream output1 = new PrintStream(outFile1);
PrintStream output2 = new PrintStream(outFile2);

/* generate key for file encryption */

SecureRandom random = new SecureRandom();
KeyGenerator keygen = KeyGenerator.getInstance("DES-EDE3");
keygen.initialize(random);
Key key = keygen.generateKey();
RawKey rkey = (RawKey) key;
byte[] yval = rkey.getEncoded();
BigInteger Bkey = new BigInteger(yval);
String w = cryptix.util.core.BI.dumpString(Bkey);
output1.println("The Encryption Key = " + w);

/* Define and Initialize Key */
Cipher des=Cipher.getInstance("DES-
EDE3/ECB/PKCS#5","Cryptix");
des.initEncrypt(key);


/* read in the input file */
      FileInputStream fis = new FileInputStream(args[0]);
byte b;
int bi;
char bc;
byte bb[] = new byte[1024];
int count=0;
output1.println("This is a copy of the input file: ");
output1.println(" ");

      while (fis.available() != 0) {
       b = (byte)  fis.read();
  bi = (int) b;
  bc = (char) b;
       output1.print(bc);
  bb[count] = b;
  count++;
                };

output1.print("\n");
output1.print("\n");
output1.println("The number of bytes in the plaintext input
file is = " + count);
      fis.close();

/* do the encryption */
int remain = count%8;
int pcount = count + remain;
byte[] bt = new byte[pcount];
int i;
for(i=0;i<pcount;i++) bt[i] = bb[i];
byte[] ciphertext = des.crypt(bt);
output1.print("\n");
output1.println("ciphertext.length = " +
ciphertext.length);

/* print out representation of ciphertext to general output
file */
BigInteger Bciph = new BigInteger(ciphertext);
w = cryptix.util.core.BI.dumpString(Bciph);
output1.println("Ciphertext = " + w);

/* print ciphertext to ciphertext specific file */
output2.write(ciphertext,0,ciphertext.length);
output2.close();

/* decrypt ciphertext from memeory */
des.initDecrypt(key);
byte[] decrypted = des.crypt(ciphertext);
BigInteger Bplain = new BigInteger(decrypted);
w = cryptix.util.core.BI.dumpString(Bplain);
output1.println("Plaintext (decrypted from memory) = " +
w);

/* write the decrypted bytes to general outputfile  */
char c;
output1.println("Following is a copy of the decrypted (from
memory) bytes: ");
output1.print("\n");
for(i=0;i<count;i++) {
  c = (char) decrypted[i];
  output1.print(c);
  }
output1.println(" ");

/* read in ciphertext from file */
      fis = new FileInputStream("DES3CIPH.out");
bb = new byte[1024];
pcount=0;
  while (fis.available() != 0) {
          b = (byte) fis.read();
      bb[pcount] = b;
  pcount++;
            };

output1.print("\n");
output1.println("The number of bytes in the ciphertext
input file is " + pcount);
      fis.close();

des.initDecrypt(key);
bt = new byte[pcount];
for(i=0;i<pcount;i++) bt[i] = bb[i];
decrypted = des.crypt(bt);
Bplain = new BigInteger(decrypted);
w = cryptix.util.core.BI.dumpString(Bplain);
output1.println("Plaintext (decrypted from cipher file) = "
+ w);

/* write the decrypted bytes to the general output file */
output1.println("Following is a copy of the decrypted (from
cipher file) bytes: ");
output1.print("\n");
for(i=0;i<count;i++) {
  c = (char) decrypted[i];
  output1.print(c);
  }
output1.println(" ");

output1.close();

      } catch (Exception e) {
            System.err.println("Caught exception " +
e.toString());
      }

}}
/***********************end of testx3DES.java**********/

/****************sample output from testx3DES.java**********/

The Encryption Key = Multi-Precision Integer 190 bits long...
      sign: Negative
magnitude: C61722CA3F7DEEA6 7E4D87A928908B47 594282C07D1D5F69


This is a copy of the input file:

Senator Hand N. Till
Washington, DC

Dear Senator:

This letter is to inform you we have
opened account no. 338907021 on your
behalf, and deposted therein a

legislative incentive payment of
$1 million.  For withdrawl, you will
need to use your password BJRGUD7693.

Yours very truly,

Arnold C. Creole
Vice President
Greater Caribbean Bank

The number of bytes in the plaintext input file is = 355

ciphertext.length = 360
Ciphertext = Multi-Precision Integer 2879 bits long...
      sign: Negative
magnitude: Hexadecimal dump of 360 bytes...
   0: 8E08C06612267EEB 4FF9AF49EDB6743D BE3BBE82EAE64261
A40BD6A6D814B230
  32: 16651BD3E90B829D 910ED9751DF82007 916C2BD72A5D53AA
CB876CC7C7CA0DFF
  64: 419B3948123A8715 7A801E129185BAA3 E159FABCFE8E98EE
89299B3964B438F6
  96: 15012D94B21F3F55 013B9B6A9B1A3474 1017229617E8D47C
9618FB74804E80D2
128: 1ECD059819B7729E FBF47E01EF4B6E67 69C99F1E212905B0
63B2F3D4725CC842
160: C84C4B55D59029D8 5551EBE5AC5A1D2C 7D09CCDEADFD214E
49B0979B07FACD4D
192: 3B626E3B718F5D46 C3D8C6B8E7279391 AFF48BE961FBA899
9ADEC794F21DE1E7
224: 4B76EFBE2E6FE416 19CFDD42D482B03D C32A459AB10E1417
C3CE45CC148BBB48
256: 315CFCBD4E45320E 750C5B1B9A6D89D9 AE5026266BDEA3D0
FD71F2D7C507879D
288: 0E0EB7B19FEDA173 06D27737673BF003 68B2DAF4747BFEF8
9C3F947E1D19C9B7
320: AD2CF4A1275C2E38 EFAAE0B2BB076ACD 7DCE861B374B63D2
E12DD856A0262A49
352: 29B2B1C281C009CF


Plaintext (decrypted from memory) = Multi-Precision Integer 2863
bits long...
      sign: Positive
magnitude: Hexadecimal dump of 358 bytes...
   0: 53656E61746F7220 48616E64204E2E20 54696C6C0D0A5761
7368696E67746F6E
  32: 2C2044430D0A0D0A 446561722053656E 61746F723A0D0A0D
0A54686973206C65
  64: 7474657220697320 746F20696E666F72 6D20796F75207765
20686176650D0A6F
  96: 70656E6564206163 636F756E74206E6F 2E20333338393037
303231206F6E2079
128: 6F75720D0A626568 616C662C20616E64 206465706F737465
6420746865726569
160: 6E20610D0A6C6567 69736C6174697665 20696E63656E7469
7665207061796D65
192: 6E74206F660D0A24 31206D696C6C696F 6E2E2020466F7220
7769746864726177
224: 6C2C20796F752077 696C6C0D0A6E6565 6420746F20757365
20796F7572207061
256: 7373776F72642042 4A52475544373639 332E0D0A0D0A596F
7572732076657279
288: 207472756C792C0D 0A0D0A41726E6F6C 6420432E20437265
6F6C650D0A566963
320: 6520507265736964 656E740D0A477265 6174657220436172
69626265616E2042
352: 616E6B000000


Following is a copy of the decrypted (from memory) bytes:

Senator Hand N. Till
Washington, DC

Dear Senator:

This letter is to inform you we have
opened account no. 338907021 on your
behalf, and deposted therein a
legislative incentive payment of
$1 million.  For withdrawl, you will
need to use your password BJRGUD7693.

Yours very truly,

Arnold C. Creole
Vice President
Greater Caribbean Bank

The number of bytes in the ciphertext input file is 360
Plaintext (decrypted from cipher file) = Multi-Precision Integer
2863 bits long...
sign: Positive
magnitude: Hexadecimal dump of 358 bytes...
   0: 53656E61746F7220 48616E64204E2E20 54696C6C0D0A5761
7368696E67746F6E
  32: 2C2044430D0A0D0A 446561722053656E 61746F723A0D0A0D
0A54686973206C65
  64: 7474657220697320 746F20696E666F72 6D20796F75207765
20686176650D0A6F
  96: 70656E6564206163 636F756E74206E6F 2E20333338393037
303231206F6E2079
128: 6F75720D0A626568 616C662C20616E64 206465706F737465

6420746865726569
160: 6E20610D0A6C6567 69736C6174697665 20696E63656E7469
7665207061796D65
192: 6E74206F660D0A24 31206D696C6C696F 6E2E2020466F7220
7769746864726177
224: 6C2C20796F752077 696C6C0D0A6E6565 6420746F20757365
20796F7572207061
256: 7373776F72642042 4A52475544373639 332E0D0A0D0A596F
7572732076657279
288: 207472756C792C0D 0A0D0A41726E6F6C 6420432E20437265
6F6C650D0A566963
320: 6520507265736964 656E740D0A477265 6174657220436172
69626265616E2042
352: 616E6B000000

Following is a copy of the decrypted (from cipher file) bytes:

Senator Hand N. Till
Washington, DC

Dear Senator:

This letter is to inform you we have
opened account no. 338907021 on your
behalf, and deposted therein a
legislative incentive payment of
$1 million.  For withdrawl, you will
need to use your password BJRGUD7693.

Yours very truly,

Arnold C. Creole
Vice President
Greater Caribbean Bank

/**********end of sample output from test2x3DES.java**********/