NTLMCryptography: Add ComputeSignKey and ComputeSealKey methods and tests

This commit is contained in:
Tal Aloni 2023-12-30 20:09:24 +02:00
parent c090de02ec
commit cb2c50a7c3
2 changed files with 84 additions and 2 deletions

View file

@ -4,8 +4,6 @@
* the GNU Lesser Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*/
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SMBLibrary.Authentication.NTLM;
@ -183,6 +181,34 @@ namespace SMBLibrary.Tests
Assert.IsTrue(isMicValid);
}
[TestMethod]
public void Test_ComputeClientSignKey()
{
// Arrange
byte[] exportedSessionKey = new byte[] { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
byte[] expected = new byte[] { 0x47, 0x88, 0xdc, 0x86, 0x1b, 0x47, 0x82, 0xf3, 0x5d, 0x43, 0xfd, 0x98, 0xfe, 0x1a, 0x2d, 0x39 };
// Act
byte[] signKey = NTLMCryptography.ComputeClientSignKey(exportedSessionKey);
// Assert
Assert.IsTrue(ByteUtils.AreByteArraysEqual(expected, signKey));
}
[TestMethod]
public void Test_ComputeClientSealKey()
{
// Arrange
byte[] exportedSessionKey = new byte[] { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
byte[] expected = new byte[] { 0x59, 0xf6, 0x00, 0x97, 0x3c, 0xc4, 0x96, 0x0a, 0x25, 0x48, 0x0a, 0x7c, 0x19, 0x6e, 0x4c, 0x58 };
// Act
byte[] sealKey = NTLMCryptography.ComputeClientSealKey(exportedSessionKey);
// Assert
Assert.IsTrue(ByteUtils.AreByteArraysEqual(expected, sealKey));
}
private static byte[] GetExportedSessionKey(byte[] sessionBaseKey, AuthenticateMessage message, byte[] serverChallenge, byte[] lmowf)
{
byte[] keyExchangeKey;

View file

@ -273,5 +273,61 @@ namespace SMBLibrary.Authentication.NTLM
return ByteUtils.AreByteArraysEqual(mic, expectedMic);
}
public static byte[] ComputeClientSignKey(byte[] exportedSessionKey)
{
return ComputeSignKey(exportedSessionKey, true);
}
public static byte[] ComputeServerSignKey(byte[] exportedSessionKey)
{
return ComputeSignKey(exportedSessionKey, false);
}
private static byte[] ComputeSignKey(byte[] exportedSessionKey, bool isClient)
{
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/524cdccb-563e-4793-92b0-7bc321fce096
string str;
if (isClient)
{
str = "session key to client-to-server signing key magic constant";
}
else
{
str = "session key to server-to-client signing key magic constant";
}
byte[] encodedString = Encoding.GetEncoding(28591).GetBytes(str);
byte[] nullTerminatedEncodedString = ByteUtils.Concatenate(encodedString, new byte[1]);
byte[] concatendated = ByteUtils.Concatenate(exportedSessionKey, nullTerminatedEncodedString);
return MD5.Create().ComputeHash(concatendated);
}
public static byte[] ComputeClientSealKey(byte[] exportedSessionKey)
{
return ComputeSealKey(exportedSessionKey, true);
}
public static byte[] ComputeServerSealKey(byte[] exportedSessionKey)
{
return ComputeSealKey(exportedSessionKey, false);
}
private static byte[] ComputeSealKey(byte[] exportedSessionKey, bool isClient)
{
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/524cdccb-563e-4793-92b0-7bc321fce096
string str;
if (isClient)
{
str = "session key to client-to-server sealing key magic constant";
}
else
{
str = "session key to server-to-client sealing key magic constant";
}
byte[] encodedString = Encoding.GetEncoding(28591).GetBytes(str);
byte[] nullTerminatedEncodedString = ByteUtils.Concatenate(encodedString, new byte[1]);
byte[] concatendated = ByteUtils.Concatenate(exportedSessionKey, nullTerminatedEncodedString);
return MD5.Create().ComputeHash(concatendated);
}
}
}