1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
/**
* Projet Copass - Coffrefort de mot passe - SIMSU Grenoble 2014
* @author Tristan Fleury : tristan.fleury@u-grenoble3.fr
*/
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
//import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
//import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import jcifs.util.Hexdump;
import jcifs.util.MD4;
public class CrypterSamba {
/**
* Constructeur de la class
*/
public void CrypterSamba(){
}
/**
* Generate an NTLM password hash
* Uses jcifs
* @param password
* @return NTLM 24-bit ANSI hash
* @throws java.io.UnsupportedEncodingException
*/
public String hashNTPassword(String password) throws UnsupportedEncodingException {
MD4 md4 = new MD4();
byte[] bpass = password.getBytes("UnicodeLittleUnmarked");
md4.engineUpdate(bpass, 0, bpass.length);
byte[] hashbytes = md4.engineDigest();
String ntHash = Hexdump.toHexString(hashbytes, 0, hashbytes.length * 2);
return ntHash;
}
public byte[] hashLMPassword(String password) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException{
byte[] cle = "KGS!@#$%".getBytes();
//Mise en conformité de la longueur de la chaine password (14)
if(password.length()>14) password = password.substring(0, 13);
while(password.length()<14) password = password.concat("\0");
//Transformation de la chaine en ASCII
byte[] asciiPassword = password.toUpperCase().getBytes("ASCII");
byte[] key1; key1 = new byte[7];
byte[] key2; key2 = new byte[7];
for(int i=0; i<14; i++){
if(i>6) key2[i-7] = asciiPassword[i];
else key1[i] = asciiPassword[i];
}
//Génération du cipher avec chaque morceau de clé
Cipher cipher1 = null;
byte[] hash1 = null;
try {
cipher1 = this.getCipher(key1);
hash1 = cipher1.doFinal(cle);
} catch (InvalidKeyException ex) {
Logger.getLogger(CrypterSamba.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(CrypterSamba.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(CrypterSamba.class.getName()).log(Level.SEVERE, null, ex);
}
Cipher cipher2 = null;
byte[] hash2 = null;
try {
cipher2 = this.getCipher(key2);
hash2 = cipher2.doFinal(cle);
} catch (InvalidKeyException ex) {
Logger.getLogger(CrypterSamba.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(CrypterSamba.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(CrypterSamba.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] retour = new byte[16];
for(int i=0; i<16; i++){
if(i<8) retour[i] = hash1[i];
else retour[i] = hash2[i-8];
}
String test = new String(retour, "ASCII");
System.out.println(Arrays.toString(hash1));
System.out.println(Arrays.toString(hash2));
System.out.println(Arrays.toString(retour));
System.out.println(test);
//System.out.println(key.toString());
return retour;
}
/**
* Return the cipher for the specified key.
* @param key The key.
* @return Cipher The cipher.
* @throws HttpException If the cipher cannot be retrieved.
*/
private Cipher getCipher(byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
final Cipher ecipher = Cipher.getInstance("DES/ECB/NoPadding");
key = setupKey(key);
ecipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DES"));
return ecipher;
}
/**
* Adds parity bits to the key.
* @param key56 The key
* @return The modified key.
*/
private byte[] setupKey(byte[] key56) {
byte[] key = new byte[8];
key[0] = (byte) ((key56[0] >> 1) & 0xff);
key[1] = (byte) ((((key56[0] & 0x01) << 6)
| (((key56[1] & 0xff) >> 2) & 0xff)) & 0xff);
key[2] = (byte) ((((key56[1] & 0x03) << 5)
| (((key56[2] & 0xff) >> 3) & 0xff)) & 0xff);
key[3] = (byte) ((((key56[2] & 0x07) << 4)
| (((key56[3] & 0xff) >> 4) & 0xff)) & 0xff);
key[4] = (byte) ((((key56[3] & 0x0f) << 3)
| (((key56[4] & 0xff) >> 5) & 0xff)) & 0xff);
key[5] = (byte) ((((key56[4] & 0x1f) << 2)
| (((key56[5] & 0xff) >> 6) & 0xff)) & 0xff);
key[6] = (byte) ((((key56[5] & 0x3f) << 1)
| (((key56[6] & 0xff) >> 7) & 0xff)) & 0xff);
key[7] = (byte) (key56[6] & 0x7f);
for (int i = 0; i < key.length; i++) {
key[i] = (byte) (key[i] << 1);
}
return key;
}
} |