以编程方式读取本地密码策略

时间:2008-11-24 10:46:39

标签: windows security winapi

是否有允许读取当前密码策略的Windows API函数?例如,最小长度,复杂性等。

如果没有阅读,是否有办法以编程方式验证策略的密码?

3 个答案:

答案 0 :(得分:5)

Security Watch Windows Domain Password Policies。您可以使用ADSI或其包装器来命中AD。我找到了VBScript sample。您可以将其翻译成您想要的任何语言:

Sub ListPasswordPolicyInfo( strDomain )
    Dim objComputer
    Set objComputer = GetObject("WinNT://" & strDomain )
    WScript.Echo "MinPasswordAge: " &  ((objComputer.MinPasswordAge) / 86400)
    WScript.Echo "MinPasswordLength: " &  objComputer.MinPasswordLength
    WScript.Echo "PasswordHistoryLength: " &  objComputer.PasswordHistoryLength
    WScript.Echo "AutoUnlockInterval: " &  objComputer.AutoUnlockInterval
    WScript.Echo "LockOutObservationInterval: " &  objComputer.LockOutObservationInterval
End Sub

Dim strDomain
Do
    strDomain = inputbox( "Please enter a domainname", "Input" )
Loop until strDomain <> ""

ListPasswordPolicyInfo( strDomain )

作为奖励,请查看LDAP Admin。它是一个开源的LDAP目录编辑器,您可以使用它来测试内容,并检查用Delphi编写的代码。

答案 1 :(得分:3)

Eugene的答案很有帮助,但并不完全符合我的要求。密码复杂性过滤器实际上可以自定义,什么是好的方式来询问Windows,这个密码是否符合要求?

我花了一段时间找到它,但功能是NetValidatePasswordPolicy。这个函数的MSDN文档非常糟糕;请查看此MSDN blog entry

答案 2 :(得分:1)

查询ActiveDirectory仅适用于加入域的计算机;并且用户可以在其中查询域控制器(可以取消授权)。

@NicholasWilson使用NetValidatePasswordPolicy的答案是好的;因为它可以为你做很多繁重的工作。它甚至可以执行您必须自己重新实现的密码质量检查。但是当您使用salted哈希存储密码(例如BCrypt或Scrypt)时,NetValidatePasswordPolicy会检查您的自定义密码历史记录失败。

但真正的问题是如何查询当前计算机(甚至是非域加入计算机的)密码策略。您可以使用以下方式查询:

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;
}
PUSER_MODALS_INFO_0 = ^USER_MODALS_INFO_0;    

PUSER_MODALS_INFO_0 info0;

NET_API_STATUS res = NetUserModalsGet(nil, 0,  out info0);

if (res <> NERR_Success)
   RaiseWin32Error(res);
try
   //Specifies the minimum allowable password length. 
   //Valid values for this element are zero through PWLEN.
   Log(info0.usrmod0_min_passwd_len);

   //Specifies, in seconds, the maximum allowable password age. 
   //A value of TIMEQ_FOREVER indicates that the password never expires. 
   //The minimum valid value for this element is ONE_DAY. 
   //The value specified must be greater than or equal to the value for the usrmod0_min_passwd_age member.
   Log(info0.usrmod0_max_passwd_age);

   //Specifies the minimum number of seconds that can elapse between the time
   //a password changes and when it can be changed again. 
   //A value of zero indicates that no delay is required between password updates. 
   //The value specified must be less than or equal to the value for the usrmod0_max_passwd_age member.
   Log(info0.usrmod0_min_passwd_age);

   //Specifies, in seconds, the amount of time between the end of the valid
   // logon time and the time when the user is forced to log off the network. 
   //A value of TIMEQ_FOREVER indicates that the user is never forced to log off. 
   //A value of zero indicates that the user will be forced to log off immediately when the valid logon time expires.
   Log(info0.usrmod0_force_logoff);

   //Specifies the length of password hi'+'story 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
   Log(info0.usrmod0_password_hist_len);
finally
   NetApiBufferFree(info0);
end;