mirror of
https://github.com/MichaelGrafnetter/DSInternals
synced 2025-01-22 06:42:56 +00:00
AD LDS WDigest Hash Calculation
This commit is contained in:
parent
12a31dc238
commit
28544d7f8a
@ -1,6 +1,7 @@
|
||||
namespace DSInternals.Common.Cryptography.Test
|
||||
{
|
||||
using DSInternals.Common;
|
||||
using DSInternals.Common.Data;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
|
||||
@ -94,6 +95,21 @@
|
||||
Assert.AreEqual(WDigestHash.HashCount, hashes.Length);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WDigestHash_Compute_LDS()
|
||||
{
|
||||
// Property value taken from AD LDS
|
||||
string expectedBlob = "3100011d000000000000000000000000af4156909297baece4e553b731d9d552da58c12e5880cad54a3f909c07b0792eec9d262783c811ad9cc7aeb1ab019fe0af4156909297baece4e553b731d9d552af4156909297baece4e553b731d9d552ec9d262783c811ad9cc7aeb1ab019fe0da58c12e5880cad54a3f909c07b0792e95e11e920c7405ca6639d932888cc11c53d9e953141b322f29eb1a02798c299042eea90067734b2a81abbc79618cc1519d9aac28e63107a495266e755f7a2babac6b5dfb3bfa3b7039058310d5b36ccc7c97824dd59b9a6a053b5fae3d8603f20a5e2bc3111c759efb3a91e3740633e83b12daad09e83cb92477ac59993c5a843b12daad09e83cb92477ac59993c5a843b12daad09e83cb92477ac59993c5a8471e7228faba51df979beef06b34f791820aa1475f40540f0db59f9d2d93fc3da5f88f6d82d185741a82c7fa79e801c6d8eae592a0ce55271a17de0b39cf1e5e9923354fb99887724cf2b10e88108776b427804b8a6d6ed92c11ecb94e40da72c0c997bc1906b1f0092d61bd0efee428b0c997bc1906b1f0092d61bd0efee428b0c997bc1906b1f0092d61bd0efee428bd93e9a9a7452dff036a67a5d5d333d7c4effe21b0afc142382943ef26024649aaa6a6a95c237f2b8efa2f13ecb0cb220";
|
||||
string password = @"Pa$$w0rd";
|
||||
string userDN = "CN=john,DC=dsinternals,DC=com";
|
||||
string namingContext = "DC=dsinternals,DC=com";
|
||||
|
||||
// Compute and compare
|
||||
byte[][] hashes = WDigestHash.ComputeHash(password.ToSecureString(), userDN, namingContext);
|
||||
byte[] blob = WDigestHash.Encode(hashes);
|
||||
Assert.AreEqual(expectedBlob, blob.ToHex());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WDigestHash_EncodeProperty()
|
||||
{
|
||||
@ -104,4 +120,4 @@
|
||||
Assert.AreEqual(blob.ToHex(), newBlob.ToHex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
private const byte DefaultReserved1Value = (byte)'1';
|
||||
|
||||
/// <summary>
|
||||
/// Calculates WDigest hashes of a password.
|
||||
/// Calculates WDigest hashes of a password, as used by AD DS.
|
||||
/// </summary>
|
||||
/// <param name="password">User's password.</param>
|
||||
/// <param name="userPrincipalName">The userPrincipalName attribute value.</param>
|
||||
@ -47,11 +47,11 @@
|
||||
// Validate the input
|
||||
Validator.AssertNotNull(password, "password");
|
||||
Validator.AssertNotNullOrWhiteSpace(samAccountName, "samAccountName");
|
||||
Validator.AssertNotNullOrWhiteSpace(netBiosDomainName, "netBiosDomainName");
|
||||
Validator.AssertNotNullOrWhiteSpace(dnsDomainName, "dnsDomainName");
|
||||
Validator.AssertNotNull(netBiosDomainName, "netBiosDomainName");
|
||||
Validator.AssertNotNull(dnsDomainName, "dnsDomainName");
|
||||
|
||||
// Note that a user does not need to have a UPN.
|
||||
if(String.IsNullOrEmpty(userPrincipalName))
|
||||
if(userPrincipalName == null)
|
||||
{
|
||||
// Construct the UPN as samAccountName@dnsDomainName
|
||||
userPrincipalName = String.Format(@"{0}@{1}", samAccountName, dnsDomainName);
|
||||
@ -155,6 +155,19 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates WDigest hashes of a password, as used by AD LDS.
|
||||
/// </summary>
|
||||
/// <param name="password">Account's password.</param>
|
||||
/// <param name="accountDN">Distinguished name of the account.</param>
|
||||
/// <param name="namingContext">Distinguished name of the account's naming context.</param>
|
||||
/// <returns>29 MD5 hashes.</returns>
|
||||
/// <remarks>SecureString is copied into managed memory while calculating the hashes, which is not the best way to deal with it.</remarks>
|
||||
public static byte[][] ComputeHash(SecureString password, string accountDN, string namingContext)
|
||||
{
|
||||
return ComputeHash(password, String.Empty, accountDN, String.Empty, namingContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the WDIGEST_CREDENTIALS structure within the supplementalCredentials attribute.
|
||||
/// </summary>
|
||||
@ -242,4 +255,4 @@
|
||||
return Encoding.UTF8.GetBytes(concatenatedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user