如何以编程方式获取强制密码历史logging组策略设置?

我如何以编程方式获取强制密码历史logging组策略设置?

研究努力

您可以在以下位置find组策略选项:

**计算机configuration\ Windows设置\安全设置\帐户策略\密码策略**

强制密码历史logging

此安全设置确定在重新使用旧密码之前必须与用户帐户关联的唯一新密码的数量。 该值必须介于0到24之间的密码。

此策略使pipe理员可以通过确保旧密码不被重复使用来增强安全性。

像所有组策略选项一样,它存储在registry中。 不幸的是它存储在一个无证的registry位置:

HKEY_LOCAL_MACHINE \ SAM \ SAM \域\帐户\˚F

在未公开的二进制blob格式 。

有一个WMI类RSOP_SecuritySettingBoolean ,但没有任何上下文,这只是一个名字挂在那里 – 我不知道如何通过COM /本地通读。

NetValidatePasswordPolicy

Windows确实提供了一个NetValidatePasswordPolicy API ,允许它validation你的密码,例如:

  • 太多糟糕的尝试
  • 帐户locking
  • locking自动重置
  • 最小密码年龄
  • 最大密码年龄
  • 密码重用

并且会根据计算机上的组策略执行所有这些操作。 除了密码历史,这一切都很好。

该function要求您传递密码哈希列表,例如:

  • $2a$14$mACnM5lzNigHMaf7O1py1OLCBgGL4tYUF0N/4rS9CwDsI7ytwL4D6
  • $2a$14$mACnM5lzNigHMaf7O1py1O3vlf6.BA8k8x3IoJ.Tq3IB/2e7g61Km
  • $2a$12$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle
  • $2a$12$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm

以及新的候选密码的散列,例如:

  • $2a$10$1JsBs47iuMNsV166PKV.u.56hlT5/tRe9V5t5FIdfA0axpDSQuNN

这将导致NetValidatePasswordPolicy检查您的当前哈希是否与任何现有的哈希匹配。 不幸的是,使用弱密码algorithm( 例如Windows使用的PBKDF2 )时,检查以前密码哈希值的整个概念才起作用。

因为我使用现代的, 昂贵的腌制的密码散列algorithm(BCrypt / SCrypt),哈希不能确定性地从密码生成 – 我不能简单地检查旧列表。 我将不得不重新刷新用户的每个以前存储的盐的新密码。

  • 这不仅是一个昂贵的操作, 可能需要12秒来检查所有24个存储的散列
  • 我不知道何时停止,因为我不知道密码历史组策略的值(例如,我将检查所有24存储的散列,当我只需要检查零)。

我曾经考虑NetValidatePasswordPolicy用24个存储密码散列的虚拟列表来调用NetValidatePasswordPolicy ,例如:

  • a
  • b
  • c
  • d
  • v
  • w
  • x

然后,API会告诉我,它的密码已经不符合历史上的任何一个。 但是API也被devise为返回给你你必须保留的东西。 然后它可能会返回:

  • $2a$10$1JsBs47iuMNsV166PKV.u.56hlT5/tRe9V5t5FIdfA0axpDSQuNN
  • a
  • b
  • c

从这我可以推断,密码的历史长度是

但是我还没有到达那里。

我已经三天了,失去了耐心。

  • 为什么微软混淆组策略?
  • 为什么微软不允许人们阅读?
  • 为什么没有logging?
  • 我如何得到这一切?

Solutions Collecting From Web of "如何以编程方式获取强制密码历史logging组策略设置?"

原来,使用RSOP_SecuritySettingBoolean (结果集策略)是一个坏主意, 因为它只适用于加入域的机器。

查询Active Directory同样只适用于加入域的计算机; 并为有能力查询域控制器(这是可以不被授予的)的用户工作。

真正的解决方案是使用NetUserModalsGet ,它可以返回你的结构,如:

 struct USER_MODALS_INFO_0 { DWORD usrmod0_min_passwd_len; DWORD usrmod0_max_passwd_age; DWORD usrmod0_min_passwd_age DWORD usrmod0_force_logoff; DWORD usrmod0_password_hist_len; //Specifies the length of password history maintained. //A new password cannot match any of the previous usrmod0_password_hist_len passwords. //Valid values for this element are zero through DEF_MAX_PWHIST. } 

 struct USER_MODALS_INFO_3 { DWORD usrmod3_lockout_duration; DWORD usrmod3_lockout_observation_window; DWORD usrmod3_lockout_threshold; } 

示例代码将是:

 Int32 GetPasswordHistoryLength() { PUSER_MODALS_INFO_0 info0; NET_API_STATUS res = NetUserModalsGet(nil, 0, out info0); if (res <> NERR_Success) RaiseWin32Error(res); try { return info0.usrmod0_password_hist_len; } finally { NetApiBufferFree(info0); } } 

该文档说最大值是DEF_MAX_PWHIST ,它在Lmaccess.h中定义为:

 // // user modals related defaults // #define MAX_PASSWD_LEN PWLEN #define DEF_MIN_PWLEN 6 #define DEF_PWUNIQUENESS 5 #define DEF_MAX_PWHIST 8 #define DEF_MAX_PWAGE TIMEQ_FOREVER // forever #define DEF_MIN_PWAGE (unsigned long) 0L // 0 days #define DEF_FORCE_LOGOFF (unsigned long) 0xffffffff // never #define DEF_MAX_BADPW 0 // no limit #define ONE_DAY (unsigned long) 01*24*3600 // 01 day 

但事实并非如此。 该策略允许用户设置最多24个。

注意 :任何代码发布到公共领域。 不需要归属