none
UWP - Smartcard Authentication / Certificate Selecting RRS feed

  • Question

  • I need to write some UWP functionality that can authenticate a user from a TPM virtual smart card. Ideally I would like to utilize a popup like the one that occurs in the browser that asks you to select a certificate and then prompts you for a pin if it is tied to a smart card like the one below.

    I have the following code from the post found here: User login with Smart Card for Windows UWP appbut I am experiencing the same issue when trying to sign "Provider could not perform the action since the context was acquired as silent."

    ReadOnlyList<Certificate> Certs;
            CertificateQuery CertQuery = new CertificateQuery();
            CertQuery.HardwareOnly = true;
    
            Certs = await CertificateStores.FindAllAsync(CertQuery);
            string strEncrypt = "test";
            IBuffer BufferToEncrypt = CryptographicBuffer.ConvertStringToBinary(strEncrypt, BinaryStringEncoding.Utf8);
    
            foreach (Certificate Cert in Certs)
            {
                Debug.WriteLine($"Cert: {Cert.Subject}");
                Debug.WriteLine($"Storagename: {Cert.KeyStorageProviderName}");
                if (Cert.HasPrivateKey && ((Cert.KeyStorageProviderName == "Microsoft Base Smart Card Crypto Provider") || Cert.KeyStorageProviderName == "Microsoft Smart Card Key Storage Provider"))
                {
                    CryptographicKey Key = null;
    
                    try
                    {
                        Key = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(Cert, HashAlgorithmNames.Sha1, CryptographicPadding.RsaPkcs1V15);
                        Debug.WriteLine("Got keypair");
    
                    }
                    catch (Exception ex)
                    {
                        // Could not open Smart Card Key Pair
                        Debug.WriteLine("Could not open Smart Card Key Pair");
                    }
    
                    if (Key != null)
                    {
                        try
                        {
                            // Try to Sign with Cert Private key 
                            IBuffer EncryptedBuffer = CryptographicEngine.Sign(Key, BufferToEncrypt);                            
                            Debug.WriteLine("Signing successful");
                        }
                        catch (Exception ex)
                        {
                            // Could not sign   
                            Debug.WriteLine("Could not sign");
                            Debug.WriteLine($"Error: {ex.Message}");
                        }
                    }
                }
            }

    Is there a way to produce the same popup? Do I have to build it myself? If not, If I choose a certificate programatically, how can I prompt for a pin and verify it?

    I'm looking for the functionality shown above that is also similar to the KeyChain.ChoosePrivateKeyAlias and IKeyChainAliasCallback that exists in Android that allows a user to pick a certificate if anybody is familiar with that as well.

    Edit 1

    Changing the line:

    IBuffer EncryptedBuffer = await CryptographicEngine.Sign(Key, BufferToEncrypt);
    

    to

    IBuffer EncryptedBuffer = await CryptographicEngine.SignAsync(Key, BufferToEncrypt);
    

    does prompt me for a pin but I still need to figure out the popup for the certificate selection vs. selecting it programmatically.

    Edit 2 You can show the "Select a Certificate" window by using

            CredentialPickerOptions options = new CredentialPickerOptions();
            options.AuthenticationProtocol = AuthenticationProtocol.Ntlm;
            options.Message = "Please select your certificate";
            options.Caption = "Select a Certificate";
            options.TargetName = ".";
            options.CredentialSaveOption = CredentialSaveOption.Hidden;
    
            CredentialPickerResults credentialsPicked = await 
            CredentialPicker.PickAsync(options);
    

    However, the CredentialPickerResults has a Credential field which is of type IBuffer. I am unclear what I am supposed to do with this to either obtain the certificate directly or use it to do a lookup in the certificate store to get the certificate that was selected.




    Thursday, April 4, 2019 5:27 PM

All replies

  • Hi ,

    This problem needs more professional support. I suggest that you might need to open a support ticket for this. Please contact our paid phone support at MS Support. You will get 1:1 support on that. Please kindly note that your support ticket will be free if it is Microsoft's issue.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 8, 2019 6:43 AM