2013-09-26 18 views
5

Ich schreibe eine Clientanwendung unter Windows, die eine SSL-Verbindung zu einem Server herstellt, und der Server fordert das Clientzertifikat zur Authentifizierung an. Der Server bietet mir eine PFX-Datei, dann ich OpenSSL Kommandozeilen-Tool verwenden, um das Zertifikat und den privaten Schlüssel wie folgt zu erhalten:SSL_CTX_use_PrivateKey_file() fehlgeschlagen

openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem 
openssl pkcs12 -in filename.pfx -nocerts -out key.pem 

danach, ich versuche, mit Funktionen das Zertifikat und den privaten Schlüssel laden von openssl wie unten, aber SSL_CTX_use_PrivateKey_file() immer fehlgeschlagen, ist die Fehlermeldung "error:0906D06C:PEM routines:PEM_read_bio:no start line", kann ich nicht herausfinden, warum, kann mir jemand eine Erleuchtung geben? Hier ist der Code.

#include "openssl/ssl.h" 
#include "openssl/err.h" 
#include <stdio.h> 
#include <string> 

int InitClientCtx() 
{ 
    OpenSSL_add_ssl_algorithms(); 

    SSL_CTX* m_pClientCtx; 
    m_pClientCtx = SSL_CTX_new(SSLv23_method()); 

    if(!m_pClientCtx) 
    { 
     return -1; 
    } 

    ::SSL_CTX_set_options(m_pClientCtx, SSL_OP_ALL); //for well-known bugs 

    int nRet = 0; 

    std::string sCertFilePath = "C:\\cert.pem"; 

    nRet = SSL_CTX_use_certificate_chain_file(m_pClientCtx, sCertFilePath.c_str()); 

    std::string sKeyPassWord = "123456"; 

    SSL_CTX_set_default_passwd_cb_userdata(m_pClientCtx, (void*)(sKeyPassWord.c_str())); 

    std::string sKeyFilePath = "C:\\key.pem"; 

    // this method returned 0, which means it failed. 
    nRet = SSL_CTX_use_PrivateKey_file(m_pClientCtx, sKeyFilePath.c_str(), SSL_FILETYPE_PEM); 

    SSL_load_error_strings(); 
    unsigned long n = ERR_get_error(); 
    char buf[1024]; 
    printf("%s\n", ERR_error_string(n, buf)); 

    nRet = SSL_CTX_check_private_key(m_pClientCtx); 
    if (nRet <= 0) 
    { 
     return -1; 
    } 

    /*std::string sCACertFilePath; 

    nRet = SSL_CTX_load_verify_locations(m_pClientCtx, sCACertFilePath.c_str(), NULL);*/ 

    return 0; 
} 

int main() 
{ 
    InitClientCtx(); 
    return 0; 
}; 

Antwort

3

Ich habe dieses Problem selbst gelöst. Ich generierte die key.pem mit OpenSSL für Windows, wenn der CMD mich auffordert, die Passphrase einzugeben, Ich habe gerade eine Eingabe eingegeben, da ich keine Passphrase brauche, aber die key.pem war ungültig (weder BEGIN noch END Marker). Wenn ich den privaten Schlüssel in Linux erzeuge, fordert das Terminal auf, dass ich einen Pass-Satz eingeben muss, und ich tue es. Dann entferne ich die Schlüssel Passphrase mit diesem Befehl:

openssl rsa -in key.pem -out newkey.pem

Danach öffne ich die key.pem in einem Texteditor, mit -----BEGIN RSA PRIVATE KEY----- beginnt und mit -----END RSA PRIVATE KEY----- enden. Und SSL_CTX_use_PrivateKey_file() funktioniert einfach gut!

+0

Sehr nützlicher Trick zum Entfernen des Passwortes einer Schlüsseldatei. _In Toolbox_ hinzufügen. – samvv

4

Der Fehler ist error:0906D06C:PEM routines:PEM_read_bio:no start line weil sowohl in der cert.pem sowie key.pem, nicht mit -----BEGIN CERTIFICATE----- und -----BEGIN ENCRYPTED PRIVATE KEY----- beginnen.

Wenn Sie Ihre cert.pem und key.pem in einem Texteditor öffnen und alles abziehen, was vor den BEGIN Markern ist, sollten Sie gut sein.

Wenn Sie ein Zertifikat und ein Schlüsselpaar mit Zertifikatsignaturanforderung erstellen, erhalten Sie diese zusätzlichen Informationen nicht.

0

Unter openssl Verzeichnis demo/openssl gibt es ein Client-Beispiel.

Wechsel:

meth = SSLv2_client_method(); 

in Ihrem Fall:

meth = SSLv23_client_method(); 

dieses Beispiel und sehen, wo es funktioniert nicht.

Sind Sie sicher, dass das Schlüsselpasswort 123456 ist?

+1

Ich glaube nicht, dass es wichtig ist. Die Unterscheidung SSLv2 vs SSLv23 ist ** nur ** wichtig, wenn Sie eine Verbindung herstellen. Im obigen Fall wird der Fehler ausgegeben, bevor eine Verbindung hergestellt wird. – Karthik

+0

Also das Problem war das Schlüsselpasswort wie ich darauf hinwies? – Cyril

+0

@Cyril Nein. Es ist die Passphrase, die zählt. – jfly

7

In meinem Fall war der Fehler, weil die PEM-Datei nicht sowohl einen Schlüssel und ein Zertifikat enthielt.

Stellen Sie sicher, Ihre Datei beide Abschnitte enthält:

-----BEGIN PRIVATE KEY----- jhajk838383jks..... 
-----END PRIVATE KEY----- 
-----BEGIN CERTIFICATE----- yoe55wjcxnshre..... 
-----END CERTIFICATE KEY----- 

I catenierten .key und .crt Dateien, die ich bereits in meiner Apache-Konfiguration hatte eine .pem Datei zu machen.

Der Fehler 'keine Startlinie' ist sicherlich irreführend, da Sie eine vollkommen gute "BEGIN" -Zeile in Ihrer PEM-Datei haben können und trotzdem den Fehler erhalten.

+0

Danke. Das hat den Trick für mich gemacht! –

Verwandte Themen