Undocumented usage of nCrypt API for Microsoft Passport Key Storage Provider
Hi
During couple of weeks I try to integrate Windows Hello inside the app. The app is written in golang, so the app is not UWP based.
The Documentation says, that proper way to integrate with Windows Hello is via Key Credential Manager this API is a part of UWP APIs, however this API is available for Windows Runtime API.
It took some time to me to integrate with this API via COM(Component Object Model), as this field in not explored well in golang, however I was able to success with it.
However this approach has 2 disadvantages:
- As we are building non-UWP app, there is no
CoreWindow
association. That actually don't allow window with biometric prompt to be tied to application. This creates additional icon in taskbar, as well as biometric prompt is not focused correctly with the app. I was able to find mention of this error here, but no good solution was provided https://github.com/microsoft/cppwinrt/issues/999 - There is no option to set UI Context message in biometric prompt. All the time the message is the same:
For security, an application needs to verify your identity
. But we would like to be able to set different message depends of application context, e.g.MyAwesomeApp wants to do something. Please confirm operation. But there is lack of this functionality in
KeyCredentialManager`
During exploring options how to mitigate this, I find out, that actually key credential
created via KeyCredentialManager
is stored in Microsoft Passport Key Storage Provider
. This can easily been checked after creating an identity using certutil
certutil -csp "Microsoft Passport Key Storage Provider" -user -key
This brought me idea, that we can use nCrypt API to create these credentials and do operations with them. Especially, what is useful, is that nCrypt provides solution for both problems by NCRYPT_USE_CONTEXT_PROPERTY and NCRYPT_WINDOW_HANDLE_PROPERTY
After some experiments I found that it's possible to create keys and do operations on them, but created keys don't trigger biometric prompt. Searching the way how to manage this, I found that this interesting plugin for KeePass mitigated this by using undocumented property NgcCacheType. The usage is just simple via NCryptSetProperty
here
So after adding it in my code, everything started working as expected. As well as both problems were solved.
I don't know how original author found this
This why I have several questions and hope some engineers from Microsoft will answer to them:
- Is it true, that
KeyCredentialManager
is just a wrapper on top ofnCrypt
API in case of identities? - Why
NgcCacheType
property is not documented anywhere and information about it is only that this string exists incryptngc.dll
- Is it legit to use
nCrypt
withMicrosoft Passport Key Storage Provider
withNgcCacheType
option? Will this option continue to exists? If no, how to mitigate issues described above? - And finally, why all of this is not documented :)
Hope get answer from someone about this 🙏
Thank in advance, Andrey