package hudson.plugins.pxe; import com.trilead.ssh2.crypto.digest.MD5; /** * Partial reimplementation of libc crypt(3) for the case that involves in */ public class Crypt { public static void main(String[] args) { String salt = "abcdefgh"; String key = "abc"; System.out.println(cryptMD5(salt, key)); } public static String cryptMD5(String salt, String key) { MD5 md5 = new MD5(); md5.update(key.getBytes()); md5.update("$1$".getBytes()); md5.update(salt.getBytes()); MD5 alt = new MD5(); alt.update(key.getBytes()); alt.update(salt.getBytes()); alt.update(key.getBytes()); byte[] buf = new byte[16]; alt.digest(buf); // each key char, add one char from alternate sum int i=key.length(); for( ; i>16; i-=16) md5.update(buf); md5.update(buf,0,i); // /* The original implementation now does something weird: for every 1 // bit in the key the first 0 is added to the buffer, for every 0 // bit the first character of the key. This does not seem to be // what was intended but we have to follow this to be compatible. */ // for (cnt = key_len; cnt > 0; cnt >>= 1) // __md5_process_bytes ((cnt & 1) != 0 ? (const char *) alt_result : key, 1, // &ctx); // for( i=key.length(); i>0; i>>=1 ) md5.update( ((i&1)!=0 ? "\0" : key.substring(0,1)).getBytes()); byte[] tmp = new byte[16]; md5.digest(tmp); for (i=0; i<1000; i++) { md5.reset(); if(i%2 != 0) md5.update(key.getBytes()); else md5.update(tmp); if(i%3 != 0) md5.update(salt.getBytes()); if(i%7 != 0) md5.update(key.getBytes()); if(i%2 != 0) md5.update(tmp); else md5.update(key.getBytes()); md5.digest(tmp); } return "$1$"+salt+"$" +b64(tmp[0], tmp[6], tmp[12],4) +b64(tmp[1], tmp[7], tmp[13],4) +b64(tmp[2], tmp[8], tmp[14],4) +b64(tmp[3], tmp[9], tmp[15],4) +b64(tmp[4], tmp[10], tmp[5],4) +b64(0,0, tmp[11],2); } /** * crypt(3) uses a modified base64 */ private static final String CODEC = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static String b64(int b2, int b1, int b0, int n) { String r =""; b2&=0xFF; b1&=0xFF; b0&=0xFF; int w = (b2<<16)|(b1<<8)|b0; for( ; n>0; n-- ) { r+=CODEC.charAt(w&0x3F); w>>=6; } return r; } }