public static byte[] nTOWFv1(String password) { if (password == null) throw new RuntimeException("Password parameter is required"); try { MD4 md4 = new MD4(); md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); return md4.digest(); } catch (UnsupportedEncodingException uee) { throw new RuntimeException(uee.getMessage()); } } public static byte[] nTOWFv2(String domain, String username, String password)
/** * Completes the hash computation by performing final operations such * as padding. At the return of this engineDigest, the MD engine is * reset. * * @return the array of bytes for the resulting hash value. */ public byte[] engineDigest () { // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 int bufferNdx = (int)(count % BLOCK_LENGTH); int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); // padding is alwas binary 1 followed by binary 0s byte[] tail = new byte[padLen + 8]; tail[0] = (byte)0x80; // append length before final transform: // save number of bits, casting the long to an array of 8 bytes // save low-order byte first. for (int i = 0; i < 8; i++) tail[padLen + i] = (byte)((count * 8) >>> (8 * i)); engineUpdate(tail, 0, tail.length); byte[] result = new byte[16]; // cast this MD4's context (array of 4 ints) into an array of 16 bytes. for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) result[i * 4 + j] = (byte)(context[i] >>> (8 * j)); // reset the engine engineReset(); return result; }
/** * Continues an MD4 message digest using the input byte. */ public void engineUpdate (byte b) { // compute number of bytes still unhashed; ie. present in buffer int i = (int)(count % BLOCK_LENGTH); count++; // update number of bytes buffer[i] = b; if (i == BLOCK_LENGTH - 1) transform(buffer, 0); }
A = FF(A, B, C, D, X[ 0], 3); D = FF(D, A, B, C, X[ 1], 7); C = FF(C, D, A, B, X[ 2], 11); B = FF(B, C, D, A, X[ 3], 19); A = FF(A, B, C, D, X[ 4], 3); D = FF(D, A, B, C, X[ 5], 7); C = FF(C, D, A, B, X[ 6], 11); B = FF(B, C, D, A, X[ 7], 19); A = FF(A, B, C, D, X[ 8], 3); D = FF(D, A, B, C, X[ 9], 7); C = FF(C, D, A, B, X[10], 11); B = FF(B, C, D, A, X[11], 19); A = FF(A, B, C, D, X[12], 3); D = FF(D, A, B, C, X[13], 7); C = FF(C, D, A, B, X[14], 11); B = FF(B, C, D, A, X[15], 19); A = GG(A, B, C, D, X[ 0], 3); D = GG(D, A, B, C, X[ 4], 5); C = GG(C, D, A, B, X[ 8], 9); B = GG(B, C, D, A, X[12], 13); A = GG(A, B, C, D, X[ 1], 3); D = GG(D, A, B, C, X[ 5], 5); C = GG(C, D, A, B, X[ 9], 9); B = GG(B, C, D, A, X[13], 13); A = GG(A, B, C, D, X[ 2], 3); D = GG(D, A, B, C, X[ 6], 5); C = GG(C, D, A, B, X[10], 9); B = GG(B, C, D, A, X[14], 13);
/** * Returns a copy of this MD object. */ public Object clone() { return new MD4(this); }
public MD4 () { super("MD4"); engineReset(); }
A = FF(A, B, C, D, X[ 0], 3); D = FF(D, A, B, C, X[ 1], 7); C = FF(C, D, A, B, X[ 2], 11); B = FF(B, C, D, A, X[ 3], 19); A = FF(A, B, C, D, X[ 4], 3); D = FF(D, A, B, C, X[ 5], 7); C = FF(C, D, A, B, X[ 6], 11); B = FF(B, C, D, A, X[ 7], 19); A = FF(A, B, C, D, X[ 8], 3); D = FF(D, A, B, C, X[ 9], 7); C = FF(C, D, A, B, X[10], 11); B = FF(B, C, D, A, X[11], 19); A = FF(A, B, C, D, X[12], 3); D = FF(D, A, B, C, X[13], 7); C = FF(C, D, A, B, X[14], 11); B = FF(B, C, D, A, X[15], 19); A = GG(A, B, C, D, X[ 0], 3); D = GG(D, A, B, C, X[ 4], 5); C = GG(C, D, A, B, X[ 8], 9); B = GG(B, C, D, A, X[12], 13); A = GG(A, B, C, D, X[ 1], 3); D = GG(D, A, B, C, X[ 5], 5); C = GG(C, D, A, B, X[ 9], 9); B = GG(B, C, D, A, X[13], 13); A = GG(A, B, C, D, X[ 2], 3); D = GG(D, A, B, C, X[ 6], 5); C = GG(C, D, A, B, X[10], 9); B = GG(B, C, D, A, X[14], 13);
/** * Returns a copy of this MD object. */ public Object clone() { return new MD4(this); }
public MD4 () { super("MD4"); engineReset(); }
public static byte[] nTOWFv1(String password) { if (password == null) throw new RuntimeException("Password parameter is required"); try { MD4 md4 = new MD4(); md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); return md4.digest(); } catch (UnsupportedEncodingException uee) { throw new RuntimeException(uee.getMessage()); } } public static byte[] nTOWFv2(String domain, String username, String password)
A = FF(A, B, C, D, X[ 0], 3); D = FF(D, A, B, C, X[ 1], 7); C = FF(C, D, A, B, X[ 2], 11); B = FF(B, C, D, A, X[ 3], 19); A = FF(A, B, C, D, X[ 4], 3); D = FF(D, A, B, C, X[ 5], 7); C = FF(C, D, A, B, X[ 6], 11); B = FF(B, C, D, A, X[ 7], 19); A = FF(A, B, C, D, X[ 8], 3); D = FF(D, A, B, C, X[ 9], 7); C = FF(C, D, A, B, X[10], 11); B = FF(B, C, D, A, X[11], 19); A = FF(A, B, C, D, X[12], 3); D = FF(D, A, B, C, X[13], 7); C = FF(C, D, A, B, X[14], 11); B = FF(B, C, D, A, X[15], 19); A = GG(A, B, C, D, X[ 0], 3); D = GG(D, A, B, C, X[ 4], 5); C = GG(C, D, A, B, X[ 8], 9); B = GG(B, C, D, A, X[12], 13); A = GG(A, B, C, D, X[ 1], 3); D = GG(D, A, B, C, X[ 5], 5); C = GG(C, D, A, B, X[ 9], 9); B = GG(B, C, D, A, X[13], 13); A = GG(A, B, C, D, X[ 2], 3); D = GG(D, A, B, C, X[ 6], 5); C = GG(C, D, A, B, X[10], 9); B = GG(B, C, D, A, X[14], 13);
/** * Completes the hash computation by performing final operations such * as padding. At the return of this engineDigest, the MD engine is * reset. * * @return the array of bytes for the resulting hash value. */ public byte[] engineDigest () { // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 int bufferNdx = (int)(count % BLOCK_LENGTH); int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); // padding is alwas binary 1 followed by binary 0s byte[] tail = new byte[padLen + 8]; tail[0] = (byte)0x80; // append length before final transform: // save number of bits, casting the long to an array of 8 bytes // save low-order byte first. for (int i = 0; i < 8; i++) tail[padLen + i] = (byte)((count * 8) >>> (8 * i)); engineUpdate(tail, 0, tail.length); byte[] result = new byte[16]; // cast this MD4's context (array of 4 ints) into an array of 16 bytes. for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) result[i * 4 + j] = (byte)(context[i] >>> (8 * j)); // reset the engine engineReset(); return result; }
/** * Returns a copy of this MD object. */ public Object clone() { return new MD4(this); }
/** * Continues an MD4 message digest using the input byte. */ public void engineUpdate (byte b) { // compute number of bytes still unhashed; ie. present in buffer int i = (int)(count % BLOCK_LENGTH); count++; // update number of bytes buffer[i] = b; if (i == BLOCK_LENGTH - 1) transform(buffer, 0); }
public MD4 () { super("MD4"); engineReset(); }
public static byte[] nTOWFv1(String password) { if (password == null) throw new RuntimeException("Password parameter is required"); try { MD4 md4 = new MD4(); md4.update(password.getBytes(SmbConstants.UNI_ENCODING)); return md4.digest(); } catch (UnsupportedEncodingException uee) { throw new RuntimeException(uee.getMessage()); } } public static byte[] nTOWFv2(String domain, String username, String password)
A = FF(A, B, C, D, X[ 0], 3); D = FF(D, A, B, C, X[ 1], 7); C = FF(C, D, A, B, X[ 2], 11); B = FF(B, C, D, A, X[ 3], 19); A = FF(A, B, C, D, X[ 4], 3); D = FF(D, A, B, C, X[ 5], 7); C = FF(C, D, A, B, X[ 6], 11); B = FF(B, C, D, A, X[ 7], 19); A = FF(A, B, C, D, X[ 8], 3); D = FF(D, A, B, C, X[ 9], 7); C = FF(C, D, A, B, X[10], 11); B = FF(B, C, D, A, X[11], 19); A = FF(A, B, C, D, X[12], 3); D = FF(D, A, B, C, X[13], 7); C = FF(C, D, A, B, X[14], 11); B = FF(B, C, D, A, X[15], 19); A = GG(A, B, C, D, X[ 0], 3); D = GG(D, A, B, C, X[ 4], 5); C = GG(C, D, A, B, X[ 8], 9); B = GG(B, C, D, A, X[12], 13); A = GG(A, B, C, D, X[ 1], 3); D = GG(D, A, B, C, X[ 5], 5); C = GG(C, D, A, B, X[ 9], 9); B = GG(B, C, D, A, X[13], 13); A = GG(A, B, C, D, X[ 2], 3); D = GG(D, A, B, C, X[ 6], 5); C = GG(C, D, A, B, X[10], 9); B = GG(B, C, D, A, X[14], 13);
/** * Completes the hash computation by performing final operations such * as padding. At the return of this engineDigest, the MD engine is * reset. * * @return the array of bytes for the resulting hash value. */ public byte[] engineDigest () { // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 int bufferNdx = (int)(count % BLOCK_LENGTH); int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); // padding is alwas binary 1 followed by binary 0s byte[] tail = new byte[padLen + 8]; tail[0] = (byte)0x80; // append length before final transform: // save number of bits, casting the long to an array of 8 bytes // save low-order byte first. for (int i = 0; i < 8; i++) tail[padLen + i] = (byte)((count * 8) >>> (8 * i)); engineUpdate(tail, 0, tail.length); byte[] result = new byte[16]; // cast this MD4's context (array of 4 ints) into an array of 16 bytes. for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) result[i * 4 + j] = (byte)(context[i] >>> (8 * j)); // reset the engine engineReset(); return result; }
/** * Returns a copy of this MD object. */ public Object clone() { return new MD4(this); }
/** * Continues an MD4 message digest using the input byte. */ public void engineUpdate (byte b) { // compute number of bytes still unhashed; ie. present in buffer int i = (int)(count % BLOCK_LENGTH); count++; // update number of bytes buffer[i] = b; if (i == BLOCK_LENGTH - 1) transform(buffer, 0); }