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**********/