如何验证用户登录名与PIN配对?是否有对应的WinAPI实现方式?
Windows 10/11 登录名与PIN配对验证的WinAPI方案
存在可直接调用的官方WinAPI实现方案,核心依赖Windows身份验证框架的底层接口,具体实现逻辑如下:
核心API选项
1. 本地任意用户PIN验证方案
使用LsaLogonUser接口配合MSV1_0身份验证包完成校验,这是目前最通用的实现方式:
- 调用前需要先获取
SE_TCB_NAME特权(Trusted Computing Base权限,通常需要本地系统权限运行进程才能持有),普通权限进程调用会返回权限不足错误 - 调用步骤:
- 调用
LsaOpenPolicy打开本地安全策略句柄 - 调用
LsaLookupAuthenticationPackage查询获取MSV1_0身份验证包的ID - 构造
KERB_INTERACTIVE_UNLOCK_LOGON结构体,将Flags字段设置为KERB_INTERACTIVE_UNLOCK_LOGON_FLAG_USE_PIN,同时填充待验证的用户名、域名、PIN信息 - 调用
LsaLogonUser传入构造好的参数,根据返回的NTSTATUS值判断配对是否有效
- 调用
- 核心伪代码示例:
NTSTATUS VerifyUserPin(wchar_t* username, wchar_t* domain, wchar_t* pin) { LSA_HANDLE hLsa = NULL; OBJECT_ATTRIBUTES objAttr = {0}; InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL); // 打开LSA策略句柄 NTSTATUS status = LsaOpenPolicy(NULL, &objAttr, POLICY_ALL_ACCESS, &hLsa); if (!NT_SUCCESS(status)) return status; // 查询MSV1_0验证包ID ULONG authPackageId; LSA_STRING packageName = RTL_CONSTANT_STRING("MSV1_0"); status = LsaLookupAuthenticationPackage(hLsa, &packageName, &authPackageId); if (!NT_SUCCESS(status)) { LsaClose(hLsa); return status; } // 构造登录验证结构 KERB_INTERACTIVE_UNLOCK_LOGON logonData = {0}; logonData.Logon.MessageType = KerbInteractiveUnlockLogon; logonData.Logon.Flags = KERB_INTERACTIVE_UNLOCK_LOGON_FLAG_USE_PIN; logonData.Logon.UserName.Buffer = username; logonData.Logon.UserName.Length = wcslen(username) * sizeof(wchar_t); logonData.Logon.LogonDomain.Buffer = domain; logonData.Logon.LogonDomain.Length = wcslen(domain) * sizeof(wchar_t); logonData.Logon.Password.Buffer = pin; logonData.Logon.Password.Length = wcslen(pin) * sizeof(wchar_t); // 发起登录验证 PVOID profileBuffer = NULL; ULONG profileBufferLength = 0; LUID logonId = {0}; HANDLE hToken = NULL; QUOTA_LIMITS quotaLimits = {0}; NTSTATUS subStatus = 0; status = LsaLogonUser( hLsa, NULL, Interactive, authPackageId, &logonData, sizeof(logonData), NULL, &logonId, &profileBuffer, &profileBufferLength, "aLimits, &hToken, &subStatus ); // 资源释放 if (profileBuffer) LsaFreeReturnBuffer(profileBuffer); if (hToken) CloseHandle(hToken); LsaClose(hLsa); return status; }
2. 当前登录用户PIN快速验证方案
如果只需要验证当前正在登录的用户的PIN,不需要指定任意用户名,可以使用更轻量的接口:
- 桌面应用可以调用
LogonUserExExW,将PIN作为密码参数传入,同时指定登录类型为LOGON32_LOGON_INTERACTIVE即可完成校验 - UWP应用可以调用
Windows.Security.Credentials.UI.UserConsentVerifier类的RequestVerificationAsync方法,无需额外权限即可完成当前用户的PIN验证
注意事项
- PIN是设备绑定的凭据,默认不支持跨设备验证,只能在PIN所属的本地设备上调用上述接口完成校验
- 如果设备加入了AD域或者Azure AD,域管理员可以配置PIN的漫游策略,这种场景下也可以在域内设备调用对应接口验证漫游PIN的有效性
内容的提问来源于stack exchange,提问作者Alex Egorov
相关产品推荐
相关产品推荐

