Bonjour,

je dois créer une class pour hasher des mots de passe au format LM password.

J'ai trouvé des infos sur la mécanique du cryptage :

1) Force the password to be 14 characters. This means dropping any characters over 14, or padding the password with "null" bytes to a length of 14.
2) Convert the password to uppercase.
3) Break the 14 character password into 2 7-character chunks.
4) Use each of the 7 character chunks as a key to encrypt the constant string KGS!@#$% using DES.
5) Concatenate the two results together to create the LM Hash.


j'ai créé la class suivante:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;
    }
}
tout semble fonctionner mais comme je ne suis pas un pro du cryptage je souhaiterais avoir des avis sur ce travail... peut être que certains on déjà eu à bosser dessus? (oui même si c'est une techno qui ne sert plus )