FileDocCategorySizeDatePackage
Crypt.javaAPI DocJava SE 5 API8962Fri Aug 26 14:56:14 BST 2005com.sun.security.auth.module

Crypt

public class Crypt extends Object
Implements the UNIX crypt(3) function, based on a direct port of the libc crypt function.

From the crypt man page:

crypt() is the password encryption routine, based on the NBS Data Encryption Standard, with variations intended (among other things) to frustrate use of hardware implementations of the DES for key search.

The first argument to crypt() is normally a user's typed password. The second is a 2-character string chosen from the set [a-zA-Z0-9./]. the salt string is used to perturb the DES algorithm in one of 4096 different ways, after which the password is used as the key to encrypt repeatedly a constant string. The returned value points to the encrypted password, in the same alphabet as the salt. The first two characters are the salt itself.

version
1.5, 01/11/00
author
Roland Schemers

Fields Summary
private static final byte[]
IP
private static final byte[]
FP
private static final byte[]
PC1_C
private static final byte[]
PC1_D
private static final byte[]
shifts
private static final byte[]
PC2_C
private static final byte[]
PC2_D
private byte[]
C
private byte[]
D
private byte[]
KS
private byte[]
E
private static final byte[]
e2
private static final byte[]
S
private static final byte[]
P
private byte[]
L
private byte[]
tempL
private byte[]
f
private byte[]
preS
Constructors Summary
public Crypt()
Creates a new Crypt object for use with the crypt method.

	// does nothing at this time
	super();
    
Methods Summary
public synchronized byte[]crypt(byte[] pw, byte[] salt)
Implements the libc crypt(3) function.

param
pw the password to "encrypt".
param
salt the salt to use.
return
A new byte[13] array that contains the encrypted password. The first two characters are the salt.

	int c, i, j, pwi;
 	byte temp;
	byte[] block = new byte[66];
	byte[] iobuf = new byte[13];

/* EXPORT DELETE START */

 	pwi = 0;

 	for(i=0; pwi < pw.length && i < 64; pwi++) {
	    c = pw[pwi];
	    for(j=0; j < 7; j++, i++) {
		block[i] = (byte) ((c>>(6-j)) & 01);
	    }
	    i++;
 	}

 	setkey(block);

 	for(i=0; i < 66; i++) {
	    block[i] = 0;
	}

 	for(i=0; i < 2; i++) {
	    c = salt[i];
	    iobuf[i] = (byte)c;
	    if(c > 'Z")
		c -= 6;
	    if(c > '9")
		c -= 7;
	    c -= '.";
	    for(j=0; j < 6; j++) {
		if( ((c>>j) & 01) != 0) {
		    temp = E[6*i+j];
		    E[6*i+j] = E[6*i+j+24];
		    E[6*i+j+24] = temp;
		}
	    }
 	}

 	for(i=0; i < 25; i++) {
 		encrypt(block,0);
	}

 	for(i=0; i < 11; i++) {
	    c = 0;
	    for(j=0; j < 6; j++) {
		c <<= 1;
		c |= block[6*i+j];
	    }
	    c += '.";
	    if(c > '9") {
		c += 7;
	    }
	    if(c > 'Z") {
		c += 6;
	    }
	    iobuf[i+2] = (byte)c;
 	}
 	//iobuf[i+2] = 0;
 	if(iobuf[1] == 0) {
	    iobuf[1] = iobuf[0];
	}
/* EXPORT DELETE END */
 	return(iobuf);
    
private voidencrypt(byte[] block, int fake)



         
	int	i;
	int t, j, k;
	int R = 32; // &L[32]

	if (KS == null) {
	    KS = new byte[16*48];
	}

	for(j=0; j < 64; j++) {
	    L[j] = block[IP[j]-1];
	}
	for(i=0; i < 16; i++) {
	    int index = i * 48;

	    for(j=0; j < 32; j++) {
		tempL[j] = L[R+j];
	    }
	    for(j=0; j < 48; j++) {
		preS[j] = (byte) (L[R+E[j]-1] ^ KS[index+j]);
	    }
	    for(j=0; j < 8; j++) {
		t = 6*j;
		k = S[j][(preS[t+0]<<5)+
			 (preS[t+1]<<3)+
			 (preS[t+2]<<2)+
			 (preS[t+3]<<1)+
			 (preS[t+4]<<0)+
			 (preS[t+5]<<4)];
		t = 4*j;
		f[t+0] = (byte) ((k>>3)&01);
		f[t+1] = (byte) ((k>>2)&01);
		f[t+2] = (byte) ((k>>1)&01);
		f[t+3] = (byte) ((k>>0)&01);
	    }
	    for(j=0; j < 32; j++) {
			L[R+j] = (byte) (L[j] ^ f[P[j]-1]);
	    }
	    for(j=0; j < 32; j++) {
			L[j] = tempL[j];
	    }
	}
	for(j=0; j < 32; j++) {
	    t = L[j];
	    L[j] = L[R+j];
	    L[R+j] = (byte)t;
	}
	for(j=0; j < 64; j++) {
		block[j] = L[FP[j]-1];
	}
    
public static voidmain(java.lang.String[] arg)
program to test the crypt routine. The first parameter is the cleartext password, the second is the salt to use. The salt should be two characters from the set [a-zA-Z0-9./]. Outputs the crypt result.

param
arg command line arguments.


	if (arg.length!=2) {
	    System.err.println("usage: Crypt password salt");
	    System.exit(1);
	}

	Crypt c = new Crypt();
	try {
	    byte result[] = c.crypt
	        (arg[0].getBytes("ISO-8859-1"), arg[1].getBytes("ISO-8859-1"));
	    for (int i=0; i<result.length; i++) {
	        System.out.println(" "+i+" "+(char)result[i]);
	    }
	} catch (java.io.UnsupportedEncodingException uee) {
	    // cannot happen
	}
    
private voidsetkey(byte[] key)


        
	int i, j, k;
	byte t;

	if (KS == null) {
	    KS = new byte[16*48];
	}

	for (i = 0; i < 28; i++) {
		C[i] = key[PC1_C[i]-1];
		D[i] = key[PC1_D[i]-1];
	}
	for (i = 0; i < 16; i++) {
		for (k = 0; k < shifts[i]; k++) {
			t = C[0];
			for (j = 0; j < 28-1; j++)
				C[j] = C[j+1];
			C[27] = t;
			t = D[0];
			for (j = 0; j < 28-1; j++)
				D[j] = D[j+1];
			D[27] = t;
		}
		for (j = 0; j < 24; j++) {
			int index = i * 48;

			KS[index+j] = C[PC2_C[j]-1];
			KS[index+j+24] = D[PC2_D[j]-28-1];
		}
	}
	for (i = 0; i < 48; i++)
		E[i] = e2[i];