private static byte[] calc_resp(byte[] nonce, byte[] data) { /* * takes a 21 byte array and treats it as 3 56-bit DES keys. The * 8 byte nonce is encrypted with each key and the resulting 24 * bytes are stored in the results array. */ byte[] response = new byte[24]; Org.BouncyCastle.Crypto.BufferedBlockCipher des = new Org.BouncyCastle.Crypto.BufferedBlockCipher( new Org.BouncyCastle.Crypto.Engines.DesEngine() ); byte[] key = null; key = setup_des_key(data, 0); des.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); int outputLen = des.ProcessBytes(nonce, 0, 8, response, 0); des.DoFinal(response, outputLen); key = setup_des_key(data, 7); des.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); outputLen = des.ProcessBytes(nonce, 0, 8, response, 8); des.DoFinal(response, outputLen); key = setup_des_key(data, 14); des.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); outputLen = des.ProcessBytes(nonce, 0, 8, response, 16); des.DoFinal(response, outputLen); return(response); }
/// <summary> /// Calculates NTLM NT response. /// </summary> /// <param name="nonce">Server nonce.</param> /// <param name="password">Password.</param> /// <returns>Returns NTLM NT response.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>nonce</b> or <b>password</b> is null reference.</exception> public static byte[] CalculateLM(byte[] nonce, string password) { if (nonce == null) { throw new ArgumentNullException("nonce"); } if (password == null) { throw new ArgumentNullException("password"); } byte[] lmBuffer = new byte[21]; byte[] magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; byte[] nullEncMagic = { 0xAA, 0xD3, 0xB4, 0x35, 0xB5, 0x14, 0x04, 0xEE }; // create Lan Manager password Org.BouncyCastle.Crypto.BufferedBlockCipher des = new Org.BouncyCastle.Crypto.BufferedBlockCipher( new Org.BouncyCastle.Crypto.Engines.DesEngine() ); byte[] key = null; // Note: In .NET DES cannot accept a weak key // this can happen for a null password if (password.Length < 1) { Buffer.BlockCopy(nullEncMagic, 0, lmBuffer, 0, 8); } else { key = PasswordToKey(password, 0); des.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); int outputLen = des.ProcessBytes(magic, 0, 8, lmBuffer, 0); des.DoFinal(lmBuffer, outputLen); } // and if a password has less than 8 characters if (password.Length < 8) { Buffer.BlockCopy(nullEncMagic, 0, lmBuffer, 8, 8); } else { key = PasswordToKey(password, 7); des.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); int outputLen = des.ProcessBytes(magic, 0, 8, lmBuffer, 8); des.DoFinal(lmBuffer, outputLen); } return(calc_resp(nonce, lmBuffer)); }
// https://markgamache.blogspot.ch/2013/01/ntlm-challenge-response-is-100-broken.html // https://asecuritysite.com/encryption/lmhash // http://www.programcreek.com/java-api-examples/index.php?api=org.bouncycastle.crypto.engines.DESEngine // http://bouncy-castle.1462172.n4.nabble.com/Sombody-tried-to-integrate-C-and-Java-with-BC-td1463998.html // http://www.java2s.com/Code/Java/Security/BasicsymmetricencryptionexamplewithpaddingandECBusingDES.htm // https://examples.javacodegeeks.com/core-java/security/des-with-ecb-example/ // https://bouncycastle.org/specifications.html public static void Test() { byte[] nonce = System.Text.Encoding.UTF8.GetBytes("Hello world"); string pw = "peanutbutter"; // pw = pw.Substring(0, 8); // 8: 8 bytes = 64 Bit (NTLM) CalculateLM(nonce, pw); CalculateLMWithBouncy(nonce, pw); byte[] key = System.Text.Encoding.UTF8.GetBytes(pw); key = PasswordToKey(pw, 0); string inputString = "foobar"; byte[] input = System.Text.Encoding.UTF8.GetBytes(inputString); byte[] magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; input = magic; /* * This will use a supplied key, and encrypt the data * This is the equivalent of DES/CBC/PKCS5Padding */ Org.BouncyCastle.Crypto.Engines.DesEngine engine = new Org.BouncyCastle.Crypto.Engines.DesEngine(); // Org.BouncyCastle.Security.CipherUtilities.GetCipher("DES/ECB/PKCS7Padding"); // Wrong - not ECB... // BufferedBlockCipher cipher = new PaddedBlockCipher(new CBCCipher(engine)); // Doesn't compile // BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new ZeroBytePadding() ); // Wrong - not ECB... // BufferedBlockCipher cipher = cipher = new BufferedBlockCipher(engine); Org.BouncyCastle.Crypto.BufferedBlockCipher cipher = cipher = new Org.BouncyCastle.Crypto.BufferedBlockCipher( new Org.BouncyCastle.Crypto.Engines.DesEngine() ); cipher.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); // lmBuffer = cyphertext // byte[] lmBuffer = new byte[cipher.GetOutputSize(input.Length)]; byte[] lmBuffer = new byte[21]; int outputLen = cipher.ProcessBytes(input, 0, input.Length, lmBuffer, 0); try { cipher.DoFinal(lmBuffer, outputLen); key = PasswordToKey(pw, 7); cipher.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key)); // des.CreateEncryptor().TransformBlock(magic, 0, 8, lmBuffer, 8); outputLen = cipher.ProcessBytes(input, 0, 8, lmBuffer, 8); cipher.DoFinal(lmBuffer, outputLen); System.Console.WriteLine(lmBuffer); // Here must be: array[20] //168 //19 //199 //248 //123 //109 //80 //19 // [0] ... } catch (Org.BouncyCastle.Crypto.CryptoException ce) { System.Console.Error.WriteLine(ce.Message); System.Environment.Exit(1); } }