Hello,
I am having a variety of issues with accessing private keys from my Metro (WinRT) code. The first and the most important one is that I can't use 'protected' private keys for signing.
First, I import a certificate and its key as shown below:
CertificateEnrollmentManager.ImportPfxDataAsync(pfxstr, "password", ExportOption.NotExportable, KeyProtectionLevel.ConsentOnly, InstallOptions.None, "Test Certificate");
Next, I try to use it to sign an arbitrary piece of data:
IReadOnlyList<Certificate> lst = await CertificateStores.FindAllAsync();
for (int i = 0; i < lst.Count; i++)
{
Certificate cert = lst[i];
if (cert.HasPrivateKey)
{
try
{
CryptographicKey cryptoKey = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(cert, HashAlgorithmNames.Sha1, CryptographicPadding.RsaPkcs1V15);
IBuffer bufIn = (new byte[20]).AsBuffer();
IBuffer bufOut = Windows.Security.Cryptography.Core.CryptographicEngine.SignHashedData(cryptoKey, bufIn);
}
catch (Exception)
{
;
}
}
}
I get an exception inside the SignHashedData() call (Provider could not perform the action because the context was acquired as silent. (Exception from HRESULT: 0x80090022)). Obviously, the underlying CryptoAPI key context is obtained with a silent flag,
which doesn't allow the CSP to show the warning. Yet, I would still like to use such private keys for signing and the consent dialog to be displayed. Is it achievable on Metro platform at all?
If it's not, then, as a minimum, I'd love to have some way to find out that a particular key had been imported with a consent option and can't be used for signing - without going through a SignHashedData() call. Could you please advise me what is the best
way of doing it?
If the certificate is imported with the KeyProtectionLevel.NoConsent level instead of KeyProtectionLevel.ConsentOnly, thesigning works as expected.
Thanks in advance,
Ken