Java/Security/DES
Содержание
Decrypt an object with DES
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import javax.crypto.Cipher;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
public class Main {
private static Object readFromFile(String filename) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(filename)));
Object object = ois.readObject();
ois.close();
return object;
}
public static void main(String[] args) throws Exception {
SecretKey key = (SecretKey) readFromFile("secretkey.dat");
SealedObject sealedObject = (SealedObject) readFromFile("sealed.dat");
String algorithmName = sealedObject.getAlgorithm();
Cipher cipher = Cipher.getInstance(algorithmName);
cipher.init(Cipher.DECRYPT_MODE, key);
String text = (String) sealedObject.getObject(cipher);
System.out.println("Text = " + text);
}
}
DES algorithm
// DesCipher - the DES encryption method
//
// The meat of this code is by Dave Zimmerman <dzimm@widget.ru>, and is:
//
// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
//
// Permission to use, copy, modify, and distribute this software
// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
// without fee is hereby granted, provided that this copyright notice is kept
// intact.
//
// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
//
// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
// HIGH RISK ACTIVITIES.
//
//
// The rest is:
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.ru>. All rights reserved.
//
// Copyright (C) 1996 by Wolfgang Platzer
// email: wplatzer@iaik.tu-graz.ac.at
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
import java.io.*;
/**
* This code is derived from the above source
* JCIFS API
* Norbert Hranitzky
*
* <p>and modified again by Michael B. Allen
*/
public class DES {
private int[] encryptKeys = new int[32];
private int[] decryptKeys = new int[32];
private int[] tempInts = new int[2];
public DES( ) {
}
// Constructor, byte-array key.
public DES( byte[] key ) {
if( key.length == 7 ) {
byte[] key8 = new byte[8];
makeSMBKey( key, key8 );
setKey( key8 );
} else {
setKey( key );
}
}
public static void makeSMBKey(byte[] key7, byte[] key8) {
int i;
key8[0] = (byte) ( ( key7[0] >> 1) & 0xff);
key8[1] = (byte)(( ((key7[0] & 0x01) << 6) | (((key7[1] & 0xff)>>2) & 0xff)) & 0xff );
key8[2] = (byte)(( ((key7[1] & 0x03) << 5) | (((key7[2] & 0xff)>>3) & 0xff)) & 0xff );
key8[3] = (byte)(( ((key7[2] & 0x07) << 4) | (((key7[3] & 0xff)>>4) & 0xff)) & 0xff );
key8[4] = (byte)(( ((key7[3] & 0x0F) << 3) | (((key7[4] & 0xff)>>5) & 0xff)) & 0xff );
key8[5] = (byte)(( ((key7[4] & 0x1F) << 2) | (((key7[5] & 0xff)>>6) & 0xff)) & 0xff );
key8[6] = (byte)(( ((key7[5] & 0x3F) << 1) | (((key7[6] & 0xff)>>7) & 0xff)) & 0xff );
key8[7] = (byte)(key7[6] & 0x7F);
for (i=0;i<8;i++) {
key8[i] = (byte)( key8[i] << 1);
}
}
/// Set the key.
public void setKey( byte[] key ) {
// CHECK PAROTY TBD
deskey( key, true, encryptKeys );
deskey( key, false, decryptKeys );
}
// Turn an 8-byte key into internal keys.
private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) {
int i, j, l, m, n;
int[] pc1m = new int[56];
int[] pcr = new int[56];
int[] kn = new int[32];
for ( j = 0; j < 56; ++j ) {
l = pc1[j];
m = l & 07;
pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
}
for ( i = 0; i < 16; ++i ) {
if ( encrypting )
m = i << 1;
else
m = (15-i) << 1;
n = m+1;
kn[m] = kn[n] = 0;
for ( j = 0; j < 28; ++j ) {
l = j+totrot[i];
if ( l < 28 )
pcr[j] = pc1m[l];
else
pcr[j] = pc1m[l-28];
}
for ( j=28; j < 56; ++j ) {
l = j+totrot[i];
if ( l < 56 )
pcr[j] = pc1m[l];
else
pcr[j] = pc1m[l-28];
}
for ( j = 0; j < 24; ++j ) {
if ( pcr[pc2[j]] != 0 )
kn[m] |= bigbyte[j];
if ( pcr[pc2[j+24]] != 0 )
kn[n] |= bigbyte[j];
}
}
cookey( kn, KnL );
}
private void cookey( int[] raw, int KnL[] ) {
int raw0, raw1;
int rawi, KnLi;
int i;
for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) {
raw0 = raw[rawi++];
raw1 = raw[rawi++];
KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
++KnLi;
KnL[KnLi] = (raw0 & 0x0003f000) << 12;
KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
KnL[KnLi] |= (raw1 & 0x0000003f);
++KnLi;
}
}
/// Encrypt a block of eight bytes.
private void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) {
squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
des( tempInts, tempInts, encryptKeys );
spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
}
/// Decrypt a block of eight bytes.
private void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) {
squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
des( tempInts, tempInts, decryptKeys );
spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
}
// The DES function.
private void des( int[] inInts, int[] outInts, int[] keys ) {
int fval, work, right, leftt;
int round;
int keysi = 0;
leftt = inInts[0];
right = inInts[1];
work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
right ^= work;
leftt ^= (work << 4);
work = ((leftt >>> 16) ^ right) & 0x0000ffff;
right ^= work;
leftt ^= (work << 16);
work = ((right >>> 2) ^ leftt) & 0x33333333;
leftt ^= work;
right ^= (work << 2);
work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
leftt ^= work;
right ^= (work << 8);
right = (right << 1) | ((right >>> 31) & 1);
work = (leftt ^ right) & 0xaaaaaaaa;
leftt ^= work;
right ^= work;
leftt = (leftt << 1) | ((leftt >>> 31) & 1);
for ( round = 0; round < 8; ++round ) {
work = (right << 28) | (right >>> 4);
work ^= keys[keysi++];
fval = SP7[ work & 0x0000003f ];
fval |= SP5[(work >>> 8) & 0x0000003f ];
fval |= SP3[(work >>> 16) & 0x0000003f ];
fval |= SP1[(work >>> 24) & 0x0000003f ];
work = right ^ keys[keysi++];
fval |= SP8[ work & 0x0000003f ];
fval |= SP6[(work >>> 8) & 0x0000003f ];
fval |= SP4[(work >>> 16) & 0x0000003f ];
fval |= SP2[(work >>> 24) & 0x0000003f ];
leftt ^= fval;
work = (leftt << 28) | (leftt >>> 4);
work ^= keys[keysi++];
fval = SP7[ work & 0x0000003f ];
fval |= SP5[(work >>> 8) & 0x0000003f ];
fval |= SP3[(work >>> 16) & 0x0000003f ];
fval |= SP1[(work >>> 24) & 0x0000003f ];
work = leftt ^ keys[keysi++];
fval |= SP8[ work & 0x0000003f ];
fval |= SP6[(work >>> 8) & 0x0000003f ];
fval |= SP4[(work >>> 16) & 0x0000003f ];
fval |= SP2[(work >>> 24) & 0x0000003f ];
right ^= fval;
}
right = (right << 31) | (right >>> 1);
work = (leftt ^ right) & 0xaaaaaaaa;
leftt ^= work;
right ^= work;
leftt = (leftt << 31) | (leftt >>> 1);
work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
right ^= work;
leftt ^= (work << 8);
work = ((leftt >>> 2) ^ right) & 0x33333333;
right ^= work;
leftt ^= (work << 2);
work = ((right >>> 16) ^ leftt) & 0x0000ffff;
leftt ^= work;
right ^= (work << 16);
work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
leftt ^= work;
right ^= (work << 4);
outInts[0] = right;
outInts[1] = leftt;
}
/// Encrypt a block of bytes.
public void encrypt( byte[] clearText, byte[] cipherText ) {
encrypt( clearText, 0, cipherText, 0 );
}
/// Decrypt a block of bytes.
public void decrypt( byte[] cipherText, byte[] clearText ) {
decrypt( cipherText, 0, clearText, 0 );
}
/**
* encrypts an array where the length must be a multiple of 8
*/
public byte[] encrypt(byte[] clearText) {
int length = clearText.length;
if (length % 8 != 0) {
System.out.println("Array must be a multiple of 8");
return null;
}
byte[] cipherText = new byte[length];
int count = length / 8;
for (int i=0; i<count; i++)
encrypt(clearText, i*8, cipherText, i*8);
return cipherText;
}
/**
* decrypts an array where the length must be a multiple of 8
*/
public byte[] decrypt(byte[] cipherText) {
int length = cipherText.length;
if (length % 8 != 0) {
System.out.println("Array must be a multiple of 8");
return null;
}
byte[] clearText = new byte[length];
int count = length / 8;
for (int i=0; i<count; i++)
encrypt(cipherText, i*8, clearText, i*8);
return clearText;
}
// Tables, permutations, S-boxes, etc.
private static byte[] bytebit = {
(byte)0x80, (byte)0x40, (byte)0x20, (byte)0x10,
(byte)0x08, (byte)0x04, (byte)0x02, (byte)0x01
};
private static int[] bigbyte = {
0x800000, 0x400000, 0x200000, 0x100000,
0x080000, 0x040000, 0x020000, 0x010000,
0x008000, 0x004000, 0x002000, 0x001000,
0x000800, 0x000400, 0x000200, 0x000100,
0x000080, 0x000040, 0x000020, 0x000010,
0x000008, 0x000004, 0x000002, 0x000001
};
private static byte[] pc1 = {
(byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
(byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
(byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
(byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
(byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
(byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
(byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
(byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
};
private static int[] totrot = {
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
};
private static byte[] pc2 = {
(byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
(byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
(byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
(byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
(byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
(byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
(byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
(byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
};
private static int[] SP1 = {
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
private static int[] SP2 = {
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
private static int[] SP3 = {
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
private static int[] SP4 = {
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
private static int[] SP5 = {
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
private static int[] SP6 = {
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
private static int[] SP7 = {
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
private static int[] SP8 = {
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/// Squash bytes down to ints.
public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts,
int outOff, int intLen ) {
for ( int i = 0; i < intLen; ++i )
outInts[outOff + i] =
( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) |
( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) |
( inBytes[inOff + i * 4 + 3] & 0xff );
}
/// Spread ints into bytes.
public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes,
int outOff, int intLen ) {
for ( int i = 0; i < intLen; ++i ) {
outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 );
outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 );
outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i];
}
}
}
DES Crypter and Decrypter
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class MainClass {
public static void main(String args[]) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
// for CBC; must be 8 bytes
byte[] initVector = new byte[] { 0x10, 0x10, 0x01, 0x04, 0x01, 0x01, 0x01, 0x02 };
AlgorithmParameterSpec algParamSpec = new IvParameterSpec(initVector);
Cipher m_encrypter = Cipher.getInstance("DES/CBC/PKCS5Padding");
Cipher m_decrypter = Cipher.getInstance("DES/CBC/PKCS5Padding");
m_encrypter.init(Cipher.ENCRYPT_MODE, key, algParamSpec);
m_decrypter.init(Cipher.DECRYPT_MODE, key, algParamSpec);
byte[] clearText = "www.jexp.ru".getBytes();
byte[] encryptedText = m_encrypter.doFinal(clearText);
byte[] decryptedText = m_decrypter.doFinal(encryptedText);
System.out.println(new String(clearText));
System.out.println(new String(encryptedText));
System.out.println(new String(decryptedText));
}
}
Des Encrypter
/*******************************************************************************
* Copyright (c) 2004 BlueOxygen Technology.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the BlueOxygen Software License v1.0
* which accompanies this distribution, and is available at
*
* Contributors:
* BlueOxygen Team - initial API and implementation
*******************************************************************************/
import java.io.UnsupportedEncodingException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/**
* @author ginanjar
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class DesEncrypter {
Cipher ecipher;
Cipher dcipher;
// 8-byte Salt
byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
};
// Iteration count
int iterationCount = 19;
public static final DesEncrypter NAGASAKTI = new DesEncrypter("NagaSakti");
private DesEncrypter(String passPhrase) {
try {
// Create the key
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance(
"PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameter to the ciphers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
// Create the ciphers
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e) {
} catch (java.security.spec.InvalidKeySpecException e) {
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
public String encrypt(String str) {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
}
return null;
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
} catch (java.io.IOException e) {
}
return null;
}
public static void main(String args[]){
String encrypted = DesEncrypter.NAGASAKTI.encrypt("bismillah");
System.out.println(encrypted);
String decrypted = DesEncrypter.NAGASAKTI.decrypt("eYLD6UnwrQE=");
System.out.println(decrypted);
}
}
DES Engine
/*******************************************************************************
* Class: : DESEngine
* Author : mbrinkley
* Creation : Nov 11, 2003 2:59:23 PM
* $Header: /cvsroot/jtds/jtds/src/main/net/sourceforge/jtds/util/DESEngine.java,v 1.3 2004/09/16 20:40:51 matt_brinkley Exp $
*
* Version: $Id: DESEngine.java,v 1.3 2004/09/16 20:40:51 matt_brinkley Exp $
******************************************************************************/
/*
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
*/
/**
* a class that provides a basic DES engine.
* Modified by Matt Brinkley (mdb) ... mainly just removed depends on external classes.
*
* @version $Id: DESEngine.java,v 1.3 2004/09/16 20:40:51 matt_brinkley Exp $
*/
public class DESEngine
// implements BlockCipher //mdb
{
protected static final int BLOCK_SIZE = 8;
private int[] workingKey = null;
/**
* standard constructor.
*/
public DESEngine()
{
}
/**
* mdb: convenient constructor
*/
public DESEngine( boolean encrypting, byte[] key )
{
init( encrypting, key );
}
/**
* initialise a DES cipher.
*
* @param encrypting whether or not we are for encryption.
* @param key the parameters required to set up the cipher.
* @exception IllegalArgumentException if the params argument is
* inappropriate.
*/
public void init(
boolean encrypting,
byte[] key) //mdb: changed parameter from CipherParameters to byte[]
{
workingKey = generateWorkingKey(encrypting, key);
//mdb: original:
/*
if (params instanceof KeyParameter)
{
workingKey = generateWorkingKey(encrypting,
((KeyParameter)params).getKey());
return;
}
throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
*/
}
public String getAlgorithmName()
{
return "DES";
}
public int getBlockSize()
{
return BLOCK_SIZE;
}
public int processBlock(
byte[] in,
int inOff,
byte[] out,
int outOff)
{
if (workingKey == null)
{
throw new IllegalStateException("DES engine not initialised");
}
if ((inOff + BLOCK_SIZE) > in.length)
{
//mdb: used to be DataLengthException
throw new IllegalArgumentException("input buffer too short");
}
if ((outOff + BLOCK_SIZE) > out.length)
{
//mdb: used to be DataLengthException
throw new IllegalArgumentException("output buffer too short");
}
desFunc(workingKey, in, inOff, out, outOff);
return BLOCK_SIZE;
}
public void reset()
{
}
/**
* what follows is mainly taken from "Applied Cryptography", by
* Bruce Schneier, however it also bears great resemblance to Richard
* Outerbridge"s D3DES...
*/
static short[] Df_Key =
{
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
};
static short[] bytebit =
{
0200, 0100, 040, 020, 010, 04, 02, 01
};
static int[] bigbyte =
{
0x800000, 0x400000, 0x200000, 0x100000,
0x80000, 0x40000, 0x20000, 0x10000,
0x8000, 0x4000, 0x2000, 0x1000,
0x800, 0x400, 0x200, 0x100,
0x80, 0x40, 0x20, 0x10,
0x8, 0x4, 0x2, 0x1
};
/*
* Use the key schedule specified in the Standard (ANSI X3.92-1981).
*/
static byte[] pc1 =
{
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
};
static byte[] totrot =
{
1, 2, 4, 6, 8, 10, 12, 14,
15, 17, 19, 21, 23, 25, 27, 28
};
static byte[] pc2 =
{
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
};
static int[] SP1 = {
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
static int[] SP2 = {
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
static int[] SP3 = {
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
static int[] SP4 = {
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
static int[] SP5 = {
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
static int[] SP6 = {
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
static int[] SP7 = {
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
static int[] SP8 = {
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/**
* generate an integer based working key based on our secret key
* and what we processing we are planning to do.
*
* Acknowledgements for this routine go to James Gillogly & Phil Karn.
* (whoever, and wherever they are!).
*/
protected int[] generateWorkingKey(
boolean encrypting,
byte[] key)
{
int[] newKey = new int[32];
boolean[] pc1m = new boolean[56],
pcr = new boolean[56];
for (int j = 0; j < 56; j++ )
{
int l = pc1[j];
pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
}
for (int i = 0; i < 16; i++)
{
int l, m, n;
if (encrypting)
{
m = i << 1;
}
else
{
m = (15 - i) << 1;
}
n = m + 1;
newKey[m] = newKey[n] = 0;
for (int j = 0; j < 28; j++)
{
l = j + totrot[i];
if ( l < 28 )
{
pcr[j] = pc1m[l];
}
else
{
pcr[j] = pc1m[l - 28];
}
}
for (int j = 28; j < 56; j++)
{
l = j + totrot[i];
if (l < 56 )
{
pcr[j] = pc1m[l];
}
else
{
pcr[j] = pc1m[l - 28];
}
}
for (int j = 0; j < 24; j++)
{
if (pcr[pc2[j]])
{
newKey[m] |= bigbyte[j];
}
if (pcr[pc2[j + 24]])
{
newKey[n] |= bigbyte[j];
}
}
}
//
// store the processed key
//
for (int i = 0; i != 32; i += 2)
{
int i1, i2;
i1 = newKey[i];
i2 = newKey[i + 1];
newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
| ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
| ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
}
return newKey;
}
/**
* the DES engine.
*/
protected void desFunc(
int[] wKey,
byte[] in,
int inOff,
byte[] out,
int outOff)
{
int work, right, left;
left = (in[inOff + 0] & 0xff) << 24;
left |= (in[inOff + 1] & 0xff) << 16;
left |= (in[inOff + 2] & 0xff) << 8;
left |= (in[inOff + 3] & 0xff);
right = (in[inOff + 4] & 0xff) << 24;
right |= (in[inOff + 5] & 0xff) << 16;
right |= (in[inOff + 6] & 0xff) << 8;
right |= (in[inOff + 7] & 0xff);
work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= work;
left ^= (work << 4);
work = ((left >>> 16) ^ right) & 0x0000ffff;
right ^= work;
left ^= (work << 16);
work = ((right >>> 2) ^ left) & 0x33333333;
left ^= work;
right ^= (work << 2);
work = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= work;
right ^= (work << 8);
right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
for (int round = 0; round < 8; round++)
{
int fval;
work = (right << 28) | (right >>> 4);
work ^= wKey[round * 4 + 0];
fval = SP7[ work & 0x3f];
fval |= SP5[(work >>> 8) & 0x3f];
fval |= SP3[(work >>> 16) & 0x3f];
fval |= SP1[(work >>> 24) & 0x3f];
work = right ^ wKey[round * 4 + 1];
fval |= SP8[ work & 0x3f];
fval |= SP6[(work >>> 8) & 0x3f];
fval |= SP4[(work >>> 16) & 0x3f];
fval |= SP2[(work >>> 24) & 0x3f];
left ^= fval;
work = (left << 28) | (left >>> 4);
work ^= wKey[round * 4 + 2];
fval = SP7[ work & 0x3f];
fval |= SP5[(work >>> 8) & 0x3f];
fval |= SP3[(work >>> 16) & 0x3f];
fval |= SP1[(work >>> 24) & 0x3f];
work = left ^ wKey[round * 4 + 3];
fval |= SP8[ work & 0x3f];
fval |= SP6[(work >>> 8) & 0x3f];
fval |= SP4[(work >>> 16) & 0x3f];
fval |= SP2[(work >>> 24) & 0x3f];
right ^= fval;
}
right = (right << 31) | (right >>> 1);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (left << 31) | (left >>> 1);
work = ((left >>> 8) ^ right) & 0x00ff00ff;
right ^= work;
left ^= (work << 8);
work = ((left >>> 2) ^ right) & 0x33333333;
right ^= work;
left ^= (work << 2);
work = ((right >>> 16) ^ left) & 0x0000ffff;
left ^= work;
right ^= (work << 16);
work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
left ^= work;
right ^= (work << 4);
out[outOff + 0] = (byte)((right >>> 24) & 0xff);
out[outOff + 1] = (byte)((right >>> 16) & 0xff);
out[outOff + 2] = (byte)((right >>> 8) & 0xff);
out[outOff + 3] = (byte)( right & 0xff);
out[outOff + 4] = (byte)((left >>> 24) & 0xff);
out[outOff + 5] = (byte)((left >>> 16) & 0xff);
out[outOff + 6] = (byte)((left >>> 8) & 0xff);
out[outOff + 7] = (byte)( left & 0xff);
}
}
Encrypt an object with DES
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
public class Main {
private static void writeToFile(String filename, Object object) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(filename)));
oos.writeObject(object);
oos.flush();
oos.close();
}
public static void main(String[] args) throws Exception {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
writeToFile("secretkey.dat", key);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
SealedObject sealedObject = new SealedObject("THIS IS A SECRET MESSAGE!", cipher);
writeToFile("sealed.dat", sealedObject);
}
}
Encrypting a File or Stream with DES
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
class DesEncrypter {
byte[] buf = new byte[1024];
Cipher ecipher;
Cipher dcipher;
DesEncrypter(SecretKey key) throws Exception{
byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 0x07, 0x72, 0x6F, 0x5A };
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
}
public void encrypt(InputStream in, OutputStream out) throws Exception{
out = new CipherOutputStream(out, ecipher);
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);
}
out.close();
}
public void decrypt(InputStream in, OutputStream out) throws Exception{
in = new CipherInputStream(in, dcipher);
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);
}
out.close();
}
}
public class Main {
public static void main(String[] argv) throws Exception {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
DesEncrypter encrypter = new DesEncrypter(key);
encrypter.encrypt(new FileInputStream("cleartext1"), new FileOutputStream("ciphertext"));
encrypter.decrypt(new FileInputStream("ciphertext"), new FileOutputStream("cleartext2"));
}
}
Encrypting an Object with DES
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
public class Main {
public static void main(String[] argv) throws Exception {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
Cipher ecipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
SealedObject so = new SealedObject(new MySecretClass(), ecipher);
String algoName = so.getAlgorithm(); // DES
Cipher dcipher = Cipher.getInstance("DES");
dcipher.init(Cipher.DECRYPT_MODE, key);
MySecretClass o = (MySecretClass) so.getObject(dcipher);
}
}
class MySecretClass implements java.io.Serializable {
String s = "the secret";
}
Encrypting a String with DES
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
class DesEncrypter {
Cipher ecipher;
Cipher dcipher;
DesEncrypter(SecretKey key) throws Exception {
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
}
public String encrypt(String str) throws Exception {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
}
public String decrypt(String str) throws Exception {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
}
}
public class Main {
public static void main(String[] argv) throws Exception {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
DesEncrypter encrypter = new DesEncrypter(key);
String encrypted = encrypter.encrypt("Don"t tell anybody!");
String decrypted = encrypter.decrypt(encrypted);
}
}
Encrypting with DES Using a Pass Phrase
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
class DesEncrypter {
Cipher ecipher;
Cipher dcipher;
byte[] salt = { (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32, (byte) 0x56, (byte) 0x35,
(byte) 0xE3, (byte) 0x03 };
DesEncrypter(String passPhrase) throws Exception {
int iterationCount = 2;
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
}
public String encrypt(String str) throws Exception {
return new BASE64Encoder().encode(ecipher.doFinal(str.getBytes()));
}
public String decrypt(String str) throws Exception {
return new String(dcipher.doFinal(new BASE64Decoder().decodeBuffer(str)));
}
}
public class Main {
public static void main(String[] argv) throws Exception {
DesEncrypter encrypter = new DesEncrypter("My Pass Phrase!");
String encrypted = encrypter.encrypt("Don"t tell anybody!");
String decrypted = encrypter.decrypt(encrypted);
}
}
Triple DES
/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
/**
* This class defines methods for encrypting and decrypting using the Triple DES
* algorithm and for generating, reading and writing Triple DES keys. It also
* defines a main() method that allows these methods to be used from the command
* line.
*/
public class TripleDES {
/**
* The program. The first argument must be -e, -d, or -g to encrypt,
* decrypt, or generate a key. The second argument is the name of a file
* from which the key is read or to which it is written for -g. The -e and
* -d arguments cause the program to read from standard input and encrypt or
* decrypt to standard output.
*/
public static void main(String[] args) {
try {
// Check to see whether there is a provider that can do TripleDES
// encryption. If not, explicitly install the SunJCE provider.
try {
Cipher c = Cipher.getInstance("DESede");
} catch (Exception e) {
// An exception here probably means the JCE provider hasn"t
// been permanently installed on this system by listing it
// in the $JAVA_HOME/jre/lib/security/java.security file.
// Therefore, we have to install the JCE provider explicitly.
System.err.println("Installing SunJCE provider.");
Provider sunjce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunjce);
}
// This is where we"ll read the key from or write it to
File keyfile = new File(args[1]);
// Now check the first arg to see what we"re going to do
if (args[0].equals("-g")) { // Generate a key
System.out.print("Generating key. This may take some time...");
System.out.flush();
SecretKey key = generateKey();
writeKey(key, keyfile);
System.out.println("done.");
System.out.println("Secret key written to " + args[1]
+ ". Protect that file carefully!");
} else if (args[0].equals("-e")) { // Encrypt stdin to stdout
SecretKey key = readKey(keyfile);
encrypt(key, System.in, System.out);
} else if (args[0].equals("-d")) { // Decrypt stdin to stdout
SecretKey key = readKey(keyfile);
decrypt(key, System.in, System.out);
}
} catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java " + TripleDES.class.getName()
+ " -d|-e|-g <keyfile>");
}
}
/** Generate a secret TripleDES encryption/decryption key */
public static SecretKey generateKey() throws NoSuchAlgorithmException {
// Get a key generator for Triple DES (a.k.a DESede)
KeyGenerator keygen = KeyGenerator.getInstance("DESede");
// Use it to generate a key
return keygen.generateKey();
}
/** Save the specified TripleDES SecretKey to the specified file */
public static void writeKey(SecretKey key, File f) throws IOException,
NoSuchAlgorithmException, InvalidKeySpecException {
// Convert the secret key to an array of bytes like this
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec keyspec = (DESedeKeySpec) keyfactory.getKeySpec(key,
DESedeKeySpec.class);
byte[] rawkey = keyspec.getKey();
// Write the raw key to the file
FileOutputStream out = new FileOutputStream(f);
out.write(rawkey);
out.close();
}
/** Read a TripleDES secret key from the specified file */
public static SecretKey readKey(File f) throws IOException,
NoSuchAlgorithmException, InvalidKeyException,
InvalidKeySpecException {
// Read the raw bytes from the keyfile
DataInputStream in = new DataInputStream(new FileInputStream(f));
byte[] rawkey = new byte[(int) f.length()];
in.readFully(rawkey);
in.close();
// Convert the raw bytes to a secret key like this
DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyfactory.generateSecret(keyspec);
return key;
}
/**
* Use the specified TripleDES key to encrypt bytes from the input stream
* and write them to the output stream. This method uses CipherOutputStream
* to perform the encryption and write bytes at the same time.
*/
public static void encrypt(SecretKey key, InputStream in, OutputStream out)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, IOException {
// Create and initialize the encryption engine
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
// Create a special output stream to do the work for us
CipherOutputStream cos = new CipherOutputStream(out, cipher);
// Read from the input and write to the encrypting output stream
byte[] buffer = new byte[2048];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
cos.write(buffer, 0, bytesRead);
}
cos.close();
// For extra security, don"t leave any plaintext hanging around memory.
java.util.Arrays.fill(buffer, (byte) 0);
}
/**
* Use the specified TripleDES key to decrypt bytes ready from the input
* stream and write them to the output stream. This method uses uses Cipher
* directly to show how it can be done without CipherInputStream and
* CipherOutputStream.
*/
public static void decrypt(SecretKey key, InputStream in, OutputStream out)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
IllegalBlockSizeException, NoSuchPaddingException,
BadPaddingException {
// Create and initialize the decryption engine
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, key);
// Read bytes, decrypt, and write them out.
byte[] buffer = new byte[2048];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(cipher.update(buffer, 0, bytesRead));
}
// Write out the final bunch of decrypted bytes
out.write(cipher.doFinal());
out.flush();
}
}