How can I encrypt bytes using a machine's TPM module?
Windows provides a (relatively) simple API to encrypt a blob using the CryptProtectData API, which we can wrap an easy to use function:
public Byte[] ProtectBytes(Byte[] plaintext)
{
   //...
}
The details of ProtectBytes are less important than the idea that you can use it quite easily:
SystemThe …
在调用时InitializeSecurityContext,我传递给TargetName参数的值是多少?
我正在调用这个函数InitializeSecurityContext:
InitializeSecurityContextA(
      @pAS.hcred,           //[in] credentials
      phContext,            //[in] optional] Context handle structure
      pszTargetName,        //[in, optional] Target name
      0,                    //[in] context requirements
      0,                    //[in] reserved1, must be zero
      SECURITY_NATIVE_DREP, //[in] target data representation
      pInput,               //[in] optional] SecBufferDescription
      0,                    //[in] reserved2, must be zero
      @pAS.hctxt,           //[in, out] pointer to context handle structure
      @OutBuffDesc,         //[in, out] pointer to SecBufferDesc
      ContextAttributes,    //[out] context attributes
      @lifetime);           //[out] expiration timestamp
我传递给pszTargetName谁?
我试过了
null: InitializeSecurityContextA(@pAS.hcred, phContext, …有人问过,并回答过.NET,但是现在是时候得到原生Win32代码的答案了:
如何验证Windows用户名和密码?
我之前问过托管代码这个问题.现在是原生解决方案的时候了.
需要指出一些更常见的解决方案的陷阱:
很多人建议查询Active Directory.如果抛出异常,那么您知道凭据无效 - 正如此stackoverflow问题中所建议的那样.
您不仅要对域帐户进行身份验证,还要进行隐式授权检查.也就是说,您正在使用模拟令牌从AD中读取属性.如果其他有效帐户无权从AD读取,该怎么办?默认情况下,所有用户都具有读取权限,但可以将域策略设置为禁用受限帐户(和/或组)的访问权限.
绑定AD会产生严重的开销,必须在客户端加载AD架构缓存(DirectoryServices使用的ADSI提供程序中的ADSI缓存).这既是网络又是AD服务器,消耗资源 - 而且对于像验证用户帐户这样的简单操作来说太昂贵了.
您依赖于非例外情况的异常失败,并假设这意味着无效的用户名和密码.然后,其他问题(例如,网络故障,AD连接故障,内存分配错误等)被错误地表示为身份验证失败.
使用DirectoryEntry该类是.NET是验证凭据的错误方法的示例:
无效的方法1a - .NET
DirectoryEntry entry = new DirectoryEntry("persuis", "iboyd", "Tr0ub4dor&3");
object nativeObject = entry.NativeObject;
无效的方法1b - .NET#2
public static Boolean CheckADUserCredentials(String accountName, String password, String domain)
{
    Boolean result;
    using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, accountName, password))
    {
        using (DirectorySearcher searcher = new DirectorySearcher(entry))
        { …我想针对域控制器验证一组凭据.例如:
Username: joel
Password: splotchy
Domain:   STACKOVERFLOW
在.NET 3.5及更高版本中,您可以使用PrincipalContext.ValidateCredentials(username, password).
否则你就麻烦了.
按照Microsoft知识库文章如何验证Microsoft操作系统上的用户凭据中的代码,我到达您调用的位置AcceptSecurityContext:
ss = AcceptSecurityContext(
      @pAS._hcred,           //[in]CredHandle structure
      phContext,             //[in,out]CtxtHandle structure
      @InBuffDesc,           //[in]SecBufferDesc structure 
      0,                     //[in]context requirement flags
      SECURITY_NATIVE_DREP,  //[in]target data representation
      @pAS._hctxt,           //[in,out]CtxtHandle strcture
      @OutBuffDesc,          //[in,out]SecBufferDesc structure
      ContextAttributes,     //[out]Context attribute flags
      @Lifetime);            //[out]Timestamp struture
除了函数失败:
SEC_E_NO_AUTHENTICATING_AUTHORITY(0x80090311)功能失败了.无法联系任何权限进行身份验证.这可能是由于以下条件:
- 身份验证方的域名不正确.
- 该域名不可用.
- 信任关系失败了.
这将是一个有用的错误,除了我可以使用以下方法从.NET 3.5验证相同的凭据:
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain))
{
    valid = context.ValidateCredentials(username, password);                
}
可能发生什么允许.NET验证一组凭据,而本机代码不能?
更新:LogonUser也失败了:
LogonUser("joel@stackoverflow.com", …