代码之家  ›  专栏  ›  技术社区  ›  Maltrap

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

  •  7
  • Maltrap  · 技术社区  · 17 年前

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

    如果不读取,是否有方法根据策略以编程方式验证密码?

    3 回复  |  直到 11 年前
        1
  •  5
  •   Eugene Yokota    17 年前

    Security Watch Windows Domain Password Policies . 你可以用打广告 ADSI 或者它的包装纸。我找到了一个 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编写的代码。

        2
  •  3
  •   Nicholas Wilson    14 年前

    尤金的回答很有帮助,但不是我所需要的。密码复杂性过滤器实际上可以定制,问Windows有什么好方法,这个密码符合要求吗?

    我花了一段时间才找到它,但功能是 NetValidatePasswordPolicy . 此功能的msdn文档很糟糕;请查看此 MSDN blog entry 相反。

        3
  •  1
  •   Ian Boyd    11 年前

    查询ActiveDirectory只适用于加入域的计算机;在该域中,用户可以查询域控制器(这是可以取消授予的功能)。

    @尼古拉斯沃尔森的使用回答 NetValidatePasswordPolicy 很好,因为它可以帮你做很多重的提升。它甚至可以执行密码质量检查,您必须重新实现自己。但是 网络验证密码策略 当使用salted散列存储密码(例如bcrypt或scrypt)时,检查自定义密码历史记录失败。

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

    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;