Detect the existence of a private key - winapi

I 'm trying to present the user a dialog to pick a certificate. Originally I used CryptUIDlgSelectCertificateFromStore with the "MY" store, but this results in picking all the certificates, where I only want the user to select between the
certificates that have private keys.
For that reason, I create a new memory store and store only the certificates for which a private key exists. I can use CryptAcquireCertificatePrivateKey to get a private key of a certificate, but this may result in a dialog box requesting a PIN for example. I don't want to use the CRYPT_ACQUIRE_SILENT_FLAG because a provider might want to show information on the key (not necessarily a pin or a smart card prompt).
Is there a way to know that there is a private key without actually acquiring it?
Thanks.

Related

Xamarin forms app: how to digitally sign using private key from keystore

I want to use asymmetric key pairs to sign/verify data sent from an Xamarin forms smartphone app to a web service.
I have an Xamarin forms smartphone app targeted at Android and iOS devices. The client on the device connects through a web service to a database and, on successful login, retrieves and sends data. Currently the user logs in, providing username and password. The password is hashed and the database user table is searched for the combination of the username and password hash. If this combination is found then the user is deemed to be legitimate and information can be retrieved and sent.
I now want to introduce another layer of security, so that each device that installs the app would need, additionally, a private key. This key would be used to produce a digital signature or hash of data sent up to the web service. When the web service receives the request, it will use the corresponding public key of the key pair to verify the signature, and only allow the request through if the signature is verified. From time to time, I may want to eliminate the user base and start afresh and I was thinking that I could do this easily by creating a new asymmetric key pair and sending the new private key out to each user whom I wanted to be able to use the system while also changing the corresponding public key on the web service to the new one. This way anyone still using the old private key would not gain access. The difficulty I have found with this approach is that I don’t know how to get a new key on to the user's device and, having done that, I don’t know how to get access to this key in the app’s code in order to create the digital hash. I have tried experimentally to look at the key store, but I don’t seem to be able to do that on an iPhone the way I can on the PC, so my question, at its simplest is, how do I get a private key onto an iPhone or an Android phone and, having got it on there, how do I get access to it in code in order to use it to generate a digital hash. Of course, I could just use symmetric encryption, and pass a password to the user base which could then be used in code to encrypt some mutually agreed piece of text and the web service, on receiving it, would use the same password to decrypt it. I just thought that the asymmetric key pair approach was a more elegant, and, in the end, more robust solution. The other point is that I want to use the .Net System.Security.Cryptography classes only, ie no third party code if possible.

How do I sign a message with a newly created Near account in a 3rd party app?

I'm setting up a new Near account, and I want to use its keys to sign a message in an app I'm building. How can I do this?
I used the wallet.nearprotocol.com page to create an account. Then, I used nearlib to connect to the testnet, and verify the account's balance and public keys.
But I couldn't find a way to add the account into the localStorage key store or otherwise access a method to sign a message. Nor could I find a wallet plugin or extension that would provide me access.
Generally the idea is that you never transfer given private key between 2 devices / security contexts.
So normally instead of getting private key out of wallet you just want to generate new key pair and request wallet to add public key.
https://github.com/nearprotocol/nearlib/blob/master/src.ts/wallet-account.ts provides relatively easy way to do it for webapp.
Note that it limits access to a give contract ID, so if you need unrestricted access you basically just need to omit contractId.
See examples at https://near.dev/ for WalletAccount usage.

How to retrieve the private key of a user certificate?

I want to retrieve the private key of a user certificate under Windows.
I use the CertOpenSystemStore and CertEnumCertificatesInStore methods to retrieve the user certificate.
Then the CryptAcquireCertificatePrivateKey method to retrieve the private key but there is a problem with the access rights.
Is this the right way to proceed?
The Certificate of a User Account is not stored in the 'Computer Store', if you need permissions on a key stored in the Computer store, you need to:
run certlm.msc
navigate to the certificate
right click > 'all Tasks' > 'Manage Private Keys ...'
set your desired permissions
If the certificate is in a user store, you must impersonate that user and access its personal store. In this case, you can export the key if the key is marked as exportable.
If the key is generated by a PKI, there is also the possibility that the key is available at the PKI but this depends strong on the configuration of the PKI

Public Key signing/verification

I'm developing an application to manage file and email encryption using (primarily) PKI. I have a Public Keyring with a list of contacts and their Public Keys.
Referring back to the olden days when I used PGP, I recall a requirement to sign public keys with your Private Key.
Is this a necessity on PKI and if so, what does this signing achieve? Is it bad practice to simply hold a list/database of people's names (and email) and their Public Key? Surely if their public key is - in any way - tampered with the encryption would fail and as you choose who you're sending or sharing the encrypted data with, even if a 'successful tamper' went unnoticed, the encrypted data wouldn't end up in the wrong hands anyway?
The whole thing about signing a public key with a private key is useful when you have a dedicated key-pair that you use only for signing, and then other key-pairs that you use for encrypting. This dedicated key-pair is your "trusted" key-pair that is somehow known to be legitimately attached to you (often by having it signed by a certificate authority or by having many trusted people sign that they have verified it's connection to you.)
You use this "trusted" private key to sign your not-quite-as-trusted public key. This way, people can un-sign/decrypt your new public-key with your trusted public-key. This is only mathematically possible if it was signed by your trusted private-key.
This process helps people to be sure that this new public-key actually belongs to you.

The container "…" must contain only one certificate and its private key

I am unable to install a mobile provisioning certificate on iOS 5 because I get this error:
The container "…" must contain only one certificate and its private key.
I used the same process that worked in the past but on iOS 5 it doesn't work and I have no idea how to export my certificate in a "desirable" state.
I was able to fix this by exporting the private key from the "Certificates" Category of Keychain, rather than exporting the Key directly.
So export the NAME of the cert, not the private key itself, and you should be good to go.
I think a more specific answer is that you...
open up Keychain app
(I am assuming you already have the key pair of your Identity in a keychain )
Like #Brent Shaffer says, choosing from "Certificates" is more straight forward
(The reason being is that the Keychain App logically groups the Certificate and private key for identities when using the "Certificates" view)
SHIFT-select both your SMIME certificate and its corresponding private key
right-click the selection and choose 'Export 2 Items'
Save as a (.p12) file with a very strong password
email the .p12 file to your email account
And from your iphone Mail app you can tap the .p12 file
and Mail will suggest to import this as a Profile. You will need the password from earlier.

Resources