À l'aide de X509Certificate avec fichier et la clé en c#
J'ai donné un certificat et un mot de passe pour un serveur qui accepte la connexion ssl. J'ai essayé de faire une connexion à ce serveur, mais l'authentification échoue, bien principalement parce que je ne sais pas comment utiliser le fichier et le mot de passe que j'ai reçu.
Voici mon code:
X509Certificate certificate = new X509Certificate(
@"c:\mySrvKeystore", KEY_PASSWORD);
public static bool ValidateCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors errors)
{
if (errors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", errors);
return false;
}
public void RunClient(string address, int port)
{
Console.WriteLine("Starting client...");
var client = new TcpClient(address, port);
Console.WriteLine("Client connected.");
var stream = new SslStream(client.GetStream(),false,
ValidateCertificate, null);
try
{
stream.AuthenticateAsClient(address);
Console.WriteLine(stream.IsAuthenticated ? "Client authenticated." : "Client is not authenticated.");
//TODO constantly read from server!
}
catch (AuthenticationException ae)
{
Console.WriteLine("Exception occured: {0}", ae.Message);
if (ae.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", ae.InnerException.Message);
}
Console.WriteLine("Failed to authenticate! closing the client...");
client.Close();
return;
}
catch (Exception ex)
{
Console.WriteLine("General exception occured {0}", ex.Message);
client.Close();
return;
}
}
Donc, comme vous pouvez le voir, il n'y a pas de code dans mon code que quelque part, dit le serveur (soit TcpClient ou SSLStream) que j'ai ce fichier et la clé!
J'ai un javacode qui se connecte à un serveur sans problème, mais je n'ai pas réussi à le convertir en c# encore. Toute aide serait super!
String keyPassword = "123456";
//String keyPassword = "importkey";
try {
KeyManagerFactory keyManagerFactory;
keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyInput = new FileInputStream("c:\\mySrvKeystore");
keyStore.load(keyInput, keyPassword.toCharArray());
keyInput.close();
keyManagerFactory.init(keyStore, keyPassword.toCharArray());
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory sslsocketfactory = sc.getSocketFactory();
this.sslsocket = (SSLSocket) sslsocketfactory.createSocket(host, port);
} catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (java.security.KeyManagementException e) {
e.printStackTrace();
} catch (java.security.KeyStoreException e) {
e.printStackTrace();
} catch (java.security.cert.CertificateException e) {
e.printStackTrace();
} catch (java.security.UnrecoverableKeyException e) {
e.printStackTrace();
} finally {}
}
public void run() {
try {
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
OutputStream outputstream = System.out;
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
//get text from server and stuff...no deal!
Mise à JOUR
Après la conversion de la clé à p12 selon gtrig le problème maintenant est IOException dans AutheneticateAsClient
méthode ici:
try
{
var certificate = new X509Certificate2(@"d:\mySrvKeystore.p12", "123456");
X509Certificate2[] X509Certificates = {certificate};
var certsCollection = new X509CertificateCollection(X509Certificates);
//IO EXCEPTION HERE-->
stream.AuthenticateAsClient(address, certsCollection, SslProtocols.Ssl2, false);
Console.WriteLine(stream.IsAuthenticated ? "Client authenticated." : "Client is not authenticated.");
//TODO constantly read from server!
}
Aussi lorsque j'utilise le SSlProtocols.Default
l'erreur est: RemoteCertificateNameMismatch, RemoteCertificateChainErrors
Je ne suis pas vraiment sûr, mais je pense qu'il a seulement le certificat et la clé privée est juste le mot de passe dans mon code. Aussi je crois qu'il est un lien, parce que je sais que le serveur de flux de données et je ne devrais pas envoyer quoi que ce soit sur le serveur. Mais à en juger par le code java, il pourrait également inclure la clé depuis le fichier de clés a été utilisé dans du code Java.
S'il vous plaît exécuter cette commande sur le JKS fichier de magasin de clés:
keytool -list -v -keystore mySrvKeystore
. Regardez pour voir si le résultat indique un "PrivateKeyEntry" ou si il y a seulement un certificat d'entrées. Le mot de passe dans votre code est le mot de passe pour ouvrir le JKS fichier de magasin de clés.Les erreurs sont de certificat que vous recevez à partir du serveur. L'adresse que vous indiquez ne correspond pas au nom dans le certificat de serveur. Vous obtenez ce message, parfois dans IE. Vous pouvez toujours accepter en lui permettant d'entrer dans votre ValidateCert fonction ( donc toujours retourner vrai). Beter peut-être est-à-assurez-vous que les certificats ne sont pas mal. Ou journal de la certs vous permettre quant à l'erreur. Lorsque vous placez un point d'arrêt dans de validatecert, vous pouvez consulter le certificat du serveur est de retour.
Dans le code java vous avez juste confiance, chaque certificat: trustAllCerts. Avez-vous essayé de changer la valeur false à True dans le validatecert()?
OriginalL'auteur Saeid Yazdani | 2013-11-07
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser AuthenticateAsClient avec une liste de certificats:
Pour éviter cert erreurs:
changement
OriginalL'auteur Ceelie
Cette réponse ne peut pas obtenir de vous tout le chemin là, mais il devrait vous permettre de fermer.
Vous a donné un KeyStore Java (JKS), contenant une clé privée et du certificat correspondant. Le mot de passe pour ouvrir le JKS selon votre code est "123456".
Parce que le JKS contient une clé privée, et en regardant votre code Java, il m'amène à croire que vous avez besoin d'un 2-way (mutuelle) connexion SSL. Que, fondamentalement signifie que vous en tant que client d'authentifier le serveur ET le serveur authentifie vous. Ce fichier JKS est vos informations d'identification à utiliser le serveur.
Alors, comment utilisez-vous cette en C#? Tout d'abord, nous allons convertir le JKS pour un PKCS12 keystore avec cette commande:
Maintenant, vous pouvez importer le fichier PKCS12 dans votre Windows fichier de clés, ce qui devrait le rendre facilement accessible à partir de C#. OU, vous pouvez l'importer dans un X509Certificate2 objet avec ce code:
Maintenant, vous pouvez utiliser le Windows fichier de clés ou le X509Certificate2 objet en C# pour établir la connexion SSL.
CryptographicException
alors que j'étais en train d'essayer avec la clé avant cette conversion. Non, le problème, c'est une nouvelle exception, lorsque j'essaie d'authentifier en tant que client. veuillez vérifier ma mise à jour ci-dessus:Au lieu de SslProtocols.Ssl2, essayez SslProtocols.Tls, SslProtocols.Tls11, ou SslProtocols.Tls12. Ssl2 n'est pas compatible avec les certificats clients.
Eh bien, je les ai tous testés, encore une exception jette 🙁
Est-il un autre message d'erreur avec le IOException?
Pas vraiment, je souhaite que je pourrais m'envoyer les fichiers pour vous 😛
OriginalL'auteur gtrig