简体   繁体   中英

TLS handshake error from … tls: client didn't provide a certificate

I have a C# RestFull client trying to connect to a Go server. Once I reach the TLS handshake stage it fails because client didn't provide a certificate .

I have verified that client certificate was associated with RestClient Object before the execution of the request.

// Initializing the client
RestClient client = new RestClient(Config.SERVER_DOMAIN);

// Adding client certificate (exported from a smart card with no private key attributes)
client.ClientCertificates = Global.cpf.getCertCollection();

// defining our request then executing it
var request = new RestRequest("users", Method.GET);
var response = await client.ExecuteTaskAsync(request);

It works only if the certificate was read from a .PFX file where the private component is there. But when I switch to smart card certificate (which has no private key attributes because the smart card doesn't want you to have them) the server doesn't receive any certificate from the client.

I understand that TLS needs a private key for the handshake stage, yet the client obj doesn't see any associated private key with the given certificate and therefore doesn't recognize the certificate as a valid one for TLS establishment.

I know that private keys can't be exported from the smart card, and I know that there has to be a way to tell RestClient object that in order to pass handshake stage, you should communicate with the smart card, however, I gave up!

Can someone point me to the right direction?

For most of the smartcards there should be minidriver or standalone CSP (Cryptographic Service Provider) available. These components act as a drivers that integrate the card with Windows cryptographic subsystem. They are usually provided by the device vendor and you should be able to get your certificate with reference to correct private key from your Windows Certificate Store once they're set up correctly.

Try to use the following method:

private static X509Certificate2 GetCertificate()
{
    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);

    try
    {
        // Note: X509Certificate2UI requires reference to System.Security
        X509Certificate2Collection certs = X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);
        if (certs != null && certs.Count > 0)
            return certs[0];
    }
    finally
    {
        store.Close();
    }

    return null;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM