2010-05-28 6 views
4

Je fais une négociation SSL3 en utilisant un SslStream, mais, malgré tous mes efforts, le SslStream n'envoie jamais de certificat client en mon nom. Voici le code:Impossible d'envoyer un certificat client via SslStream

SSLConnection = new System.Net.Security.SslStream(SSLInOutStream, false, new System.Net.Security.RemoteCertificateValidationCallback(AlwaysValidRemoteCertificate), new System.Net.Security.LocalCertificateSelectionCallback(ChooseLocalCertificate)); 

X509CertificateCollection CC = new X509CertificateCollection(); 
CC.Add(Org.BouncyCastle.Security.DotNetUtilities.ToX509Certificate(MyLocalCertificate)); 

SSLConnection.AuthenticateAsClient("test", CC, System.Security.Authentication.SslProtocols.Ssl3, false); 

puis je AlwaysValidRemoteCertificate juste retourner vrai, et ChooseLocalCertificate retourner l'élément zeroth du tableau.

Le code a probablement l'air un peu bizarre parce que le projet est un peu bizarre, mais je pense que ce n'est pas le cas ici. La négociation SSL se termine. Le problème est qu'au lieu d'envoyer un message de certificat en mon nom (dans le processus de négociation), avec le certificat codé ASN.1 (MyLocalCertificate), le SslStream envoie un numéro d'alerte SSL 41 (pas de certificat), puis continue. Je le sais par reniflage de paquets. Une fois la négociation terminée, le SslStream marque IsAuthenticated comme vrai, IsMutuallyAuthenticated comme faux et son membre LocalCertificate est null. J'ai l'impression qu'il me manque probablement quelque chose d'assez évident ici, donc des idées seraient appréciées. Je suis un novice en matière de SSL, et ce projet est hors des sentiers battus, donc je suis un peu perdu.

P.S. 1: La routine My ChooseLocalCertificate est appelée deux fois au cours de la négociation, et renvoie un certificat valide (pour autant que je sache), non nul à chaque fois.

P.S. 2: SSLInOutStream est ma propre classe, pas un NetworkStream. Comme je l'ai dit, cependant, la poignée de main se déroule normalement normalement, donc je doute que ce soit le coupable ... mais qui sait?

+0

Veuillez fournir un lien vers la documentation de l'API. – erickson

Répondre

5

Je ne suis pas familier avec l'API Bouncycastle .NET pour SSL, mais à première vue, je suppose que vous ne fournissez pas la clé privée de l'API.

Même si la clé privée elle-même n'est jamais envoyée au serveur, il est nécessaire de signer numériquement certaines données afin de prouver au serveur que vous la détenez. Il devrait y avoir une API pour fournir la clé privée pour cette opération de signature.

7

Pour une raison quelconque, le site ne me laissera pas laisser un commentaire sur la solution affichée ci-dessus, mais il a résolu mon problème. Voici mon commentaire:

Hé, c'était une bonne idée, et ça a réglé mon problème. Merci beaucoup. La classe C# X509Certificate ne semble pas prendre en charge la définition d'une clé privée, contrairement à la classe fille X509Certificate2. Je devais singe un peu avec des trucs BouncyCastle, mais la mise en œuvre (si quelqu'un dont il a besoin à l'avenir) est la suivante:

X509CertificateCollection CC = new X509CertificateCollection(); 
X509Certificate2 C2 = new X509Certificate2(MyLocalCertificate.GetEncoded()); 
C2.PrivateKey = Org.BouncyCastle.Security.DotNetUtilities.ToRSA((Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)MyPrivateKey.Private); 
CC.Add(C2); 

MyLocalCertificate est une instance de la classe X509Certificate de bouncycastle et MyPrivateKey est une instance de AsymmetricCipherKeyPair de bouncycastle .

Questions connexes