Frage

Ich brauche eine sichere Kommunikation zwischen verschiedenen Prozessen zu schaffen, die TCP / IP-Sockets für die Kommunikation verwenden. Ich mag sowohl die Authentifizierung und Verschlüsselung. Anstatt neu erfinden das Rad ich wirklich SSL verwenden möchte und die SslStream Klasse und selbstsignierte Zertifikate. Was ich tun möchte, ist der Remote-Prozess das Zertifikat gegen eine bekannte Kopie in meinem lokalen Anwendung zu validieren. (Es braucht keine Zertifizierungsstelle zu sein, weil ich für die Zertifikate beabsichtigen manuell kopiert werden um).

Um dies zu tun, möchte ich die Anwendung in der Lage sein, um automatisch eine neue certifiate das erste Mal, erzeugen sie ausgeführt wird. Neben Makecert.exe sieht es aus wie Link zeigt eine Art und Weise selbstsignierte Zertifikate automatisch zu generieren, so dass ein Start ist.

Ich habe an dem AuthenticateAsServer und AuthenticateAsClient Methoden der SslStream aussieht. Sie können Rückrufe zur Überprüfung zur Verfügung stellen, so sieht es aus wie es möglich ist. Aber jetzt, wo ich in die Details davon bin, ich glaube wirklich nicht, es möglich ist, dies zu tun.

Bin ich in der richtigen Richtung? Gibt es eine bessere Alternative? Hat jemand etwas ähnliches vor (im Grunde Peer-to-Peer-SSL statt Client-Server) gemacht?

War es hilfreich?

Lösung

Schritt 1: Erstellen eines selbstsignierten Zertifikat:

  • Ich habe die Certificate.cs Klasse von Doug Cook-
  • Ich habe diesen Code, um eine PFX-Zertifikatsdatei zu generieren:

    byte[] c = Certificate.CreateSelfSignCertificatePfx(
            "CN=yourhostname.com", //host name
            DateTime.Parse("2000-01-01"), //not valid before
            DateTime.Parse("2010-01-01"), //not valid after
            "mypassword"); //password to encrypt key file
    
        using (BinaryWriter binWriter = new BinaryWriter(
            File.Open(@"testcert.pfx", FileMode.Create)))
        {
            binWriter.Write(c);
        }
    

Schritt 2: Laden Sie das Zertifikat

    X509Certificate cert = new X509Certificate2(
                            @"testcert.pfx", 
                            "mypassword");

Schritt 3: Um es zusammen

  • I basiert es auf dieser sehr einfachen SslStream Beispiel
  • Sie erhalten einen Kompilierung Fehler über die SslProtocolType Aufzählung erhalten. Ändern Sie einfach das von SslProtocolType.Default zu SslProtocols.Default
  • Es waren drei Warnungen über veraltete Funktionen. Ich ersetzen sie alle mit dem vorgeschlagenen Ersatz.
  • I ersetzt diese Zeile in dem Server Program.cs mit der Linie-Datei aus Schritt 2:

    X509Certificate cert = getServerCert ();

  • In der Datei-Client Program.cs, stellen Sie sicher, dass Sie setzen servername = yourhostname.com (und es stimmt mit dem Namen im Zertifikat)

  • In dem Client-Program.cs, schlägt die CertificateValidationCallback Funktion, weil sslPolicyErrors einen RemoteCertificateChainErrors enthält. Wenn Sie ein wenig tiefer graben, ist dies, weil die ausstellende Behörde, die das Zertifikat signiert ist kein vertrauenswürdiges Stamm ist.
  • I don `t die Benutzereinfuhrbescheinigungen in mit in den Stammspeicher erhalten mag, etc., so habe ich einen Sonderfall dafür, und ich überprüfen, ob certificate.GetPublicKeyString () mit dem öffentlichen Schlüssel gleich ist, dass ich für diesen Server gespeichert haben. Wenn es zutrifft, kehre ich von dieser Funktion wahr. Das scheint zu funktionieren.

Schritt 4: Client-Authentifizierung

Hier ist, wie mein Client authentifiziert (es ist ein wenig anders als der Server):

TcpClient client = new TcpClient();
client.Connect(hostName, port);

SslStream sslStream = new SslStream(client.GetStream(), false,
    new RemoteCertificateValidationCallback(CertificateValidationCallback),
    new LocalCertificateSelectionCallback(CertificateSelectionCallback));

bool authenticationPassed = true;
try
{
    string serverName = System.Environment.MachineName;

    X509Certificate cert = GetServerCert(SERVER_CERT_FILENAME, SERVER_CERT_PASSWORD);
    X509CertificateCollection certs = new X509CertificateCollection();
    certs.Add(cert);

    sslStream.AuthenticateAsClient(
        serverName,
        certs,
        SslProtocols.Default,
        false); // check cert revokation
}
catch (AuthenticationException)
{
    authenticationPassed = false;
}
if (authenticationPassed)
{
    //do stuff
}

Die CertificateValidationCallback ist das gleiche wie in dem Server-Fall, aber beachten Sie, wie AuthenticateAsClient eine Sammlung von Zertifikaten nimmt, nicht nur ein Zertifikat. Also, müssen Sie einen LocalCertificateSelectionCallback hinzufügen, wie folgt aus (in diesem Fall ich nur ein Client-Zertifikat so dass ich nur die erste in der Sammlung zurück):

static X509Certificate CertificateSelectionCallback(object sender,
    string targetHost,
    X509CertificateCollection localCertificates,
    X509Certificate remoteCertificate,
    string[] acceptableIssuers)
{
    return localCertificates[0];
}

Andere Tipps

Sie können auch sehen dieses Beispiel Beispiel Asynchronous SslStream Client / Server-Implementierung http: // blogs.msdn.com/joncole/archive/2007/06/13/sample-asynchronous-sslstream-client-server-implementation.aspx

Wenn Zertifikat nicht erzeugt wird, richtig können Sie den Server-Modus SSL erhalten Ausnahme ein Zertifikat mit dem zugehörigen privaten Schlüssel verwenden müssen.

Grundzertifikat Beispiel

makecert -sr Localmachine -ss Mein -n CN = Test -sky Austausch -sk 123456

oder

als externe Datei

makecert -sr Localmachine -ss Mein -n CN = Test -sky Austausch -sk 123456 c: \ Test.cer

Certificate Creation Tool (Makecert.exe)
http://msdn.microsoft.com/en- us / library / bfsktky3% 28VS.80% 29.aspx

Was Sie vorschlagen klingt für mich in Ordnung, außer, dass es klingt wie Sie den Rückruf warten gesuchte bis um aufgerufen wird, um das Zertifikat zu generieren. Ich glaube nicht, dass das fliegen; AFAIK, Sie haben ein gültiges Zertifikat liefern, wenn Sie AuthenticateAsX aufrufen.

Allerdings sind diese Klassen außer Kraft gesetzt werden; so in der Theorie, könnten Sie eine abgeleitete Klasse erstellen, die zuerst überprüft, ob ein Zertifikat erzeugt werden muss, erzeugt er, wenn es sein muss, dann die Methode Mutter AuthenticateAsX aufruft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top