Frage

Ich habe eine C / C ++ Anwendung und ich brauche eine X509 pem Zertifikat sowohl einen öffentlichen und einen privaten Schlüssel enthält, zu erstellen. Das Zertifikat kann selbst signiert oder unsigniert wird, keine Rolle spielt.

Ich mag diese in einer App tun, nicht von der Kommandozeile.

Was OpenSSL Funktionen wird dies für mich tun? Jeder Beispielcode ist ein Bonus!

War es hilfreich?

Lösung

Sie müssen sich mit der Terminologie und Mechanismen zuerst vertraut zu machen.

Ein X.509 Zertifikat , per Definition, nicht enthält einen privaten Schlüssel. Stattdessen ist es eine CA-signierte Version des öffentlichen Schlüssels (zusammen mit allen Attributen der CA legt in die Signatur). Das PEM-Format wirklich unterstützt nur getrennte Speicherung der Schlüssel und das Zertifikat -. Sie können sie aber dann die beiden verketten

In jedem Fall müssen Sie mehr als 20 verschiedene Funktionen des OpenSSL-API aufrufen, um einen Schlüssel und ein selbst signiertes Zertifikat zu erstellen. Ein Beispiel hierfür ist in der OpenSSL Quelle selbst, in Demos / x509 / mkcert.c

Für eine ausführlichere Antwort, bitte unter Nathan Osman Erklärung sehen.

Andere Tipps

Ich weiß, dass dies eine sehr spät ist (und lange) Antwort. Aber wenn man bedenkt, wie gut diese Frage in Suchmaschinen-Ergebnissen Rang scheint, dachte ich, es könnte sich lohnen für eine anständige Antwort zu schreiben.

Eine Menge von dem, was Sie unten lesen werden von diese Demo und die OpenSSL-Dokumentation. Der folgende Code gilt sowohl für C und C ++.


Bevor wir ein Zertifikat tatsächlich schaffen können, brauchen wir einen privaten Schlüssel erstellen. OpenSSL liefert die EVP_PKEY Struktur ein Algorithmus-unabhängige privaten Schlüssel im Speicher zum Speichern. Diese Struktur wird in openssl/evp.h erklärt wird aber von openssl/x509.h enthalten (die wir später benötigen), so müssen Sie nicht wirklich explizit den Header enthalten.

Um eine EVP_PKEY Struktur zuzuordnen, verwenden wir EVP_PKEY_new :

EVP_PKEY * pkey;
pkey = EVP_PKEY_new();

Es gibt auch eine entsprechende Funktion für die Struktur zu befreien - EVP_PKEY_free - die ein einziges Argument akzeptiert. Die EVP_PKEY Struktur oben initialisiert

Jetzt brauchen wir einen Schlüssel zu generieren. Für unser Beispiel werden wir einen RSA-Schlüssel generieren. Dies geschieht mit der RSA_generate_key Funktion, die in openssl/rsa.h deklariert wird. Diese Funktion gibt einen Zeiger auf eine RSA Struktur.

Ein einfacher Aufruf der Funktion könnte wie folgt aussehen:

RSA * rsa;
rsa = RSA_generate_key(
    2048,   /* number of bits for the key - 2048 is a sensible value */
    RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
    NULL,   /* callback - can be NULL if we aren't displaying progress */
    NULL    /* callback argument - not needed in this case */
);

Wenn der Rückgabewert von RSA_generate_key NULL ist, dann ist etwas schief gelaufen. Wenn nicht, dann haben wir jetzt einen RSA-Schlüssel, und wir können es in unserer EVP_PKEY Struktur aus früherem zuweisen:

EVP_PKEY_assign_RSA(pkey, rsa);

Die RSA Struktur automatisch freigegeben wird, wenn die EVP_PKEY Struktur befreit wird.


Jetzt für das Zertifikat selbst.

OpenSSL verwendet die X509 Struktur ein X509-Zertifikat im Speicher darstellen. Die Definition für diese Struktur ist in openssl/x509.h. Die erste Funktion gehen zu müssen, wir X509_new . Seine Verwendung ist relativ einfach:

X509 * x509;
x509 = X509_new();

Wie bei EVP_PKEY war, gibt es eine entsprechende Funktion, um die Struktur zu befreien -. X509_free

Jetzt müssen wir einige Eigenschaften des Zertifikats setzen einige X509_* Funktionen:

ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);

Hier wird die Seriennummer unseres Zertifikats auf ‚1‘. Einig Open-Source-HTTP-Server verweigert ein Zertifikat mit einer Seriennummer von ‚0‘ zu akzeptieren, die die Standardeinstellung. Der nächste Schritt ist es, die Zeitspanne angeben, während der das Zertifikat tatsächlich gültig ist. Wir tun das mit den folgenden zwei Funktionsaufrufe:

X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);

Die erste Zeile setzt das notBefore Eigenschaft Zertifikat auf die aktuelle Zeit. (Die X509_gmtime_adj Funktion fügt die angegebene Anzahl von Sekunden auf die aktuelle Zeit - in diesem Fall keine.) Die zweite Zeile der notAfter Eigenschaft auf 365 Tage ab jetzt das Zertifikat setzt (60 Sekunden * 60 Minuten * 24 Stunden * 365 Tage)

Jetzt müssen wir den öffentlichen Schlüssel für unser Zertifikat, um den Schlüssel erzeugten wir früher:

X509_set_pubkey(x509, pkey);

Da dies ein selbst signiertes Zertifikat ist, setzen wir den Namen des Emittenten auf den Namen des Themas. Der erste Schritt in diesem Prozess ist das Thema Namen zu bekommen:

X509_NAME * name;
name = X509_get_subject_name(x509);

Wenn Sie jemals ein selbst signiertes Zertifikat auf der Kommandozeile, bevor erstellt haben, werden Sie wahrscheinlich für einen Ländercode erinnere mich gefragt. Hier ist, wo wir es zusammen mit der Organisation zur Verfügung stellen ( ‚O‘) und Common Name (KN):

X509_NAME_add_entry_by_txt(name, "C",  MBSTRING_ASC,
                           (unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O",  MBSTRING_ASC,
                           (unsigned char *)"MyCompany Inc.", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
                           (unsigned char *)"localhost", -1, -1, 0);

(Ich verwende den Wert ‚CA‘hier, weil ich bin Kanadier und das ist unser Ländercode. Beachten Sie auch, dass Parameter # 4 muss ausdrücklich auf eine unsigned char * gegossen werden.)

Jetzt können wir tatsächlich die Ausstellernamen gesetzt:

X509_set_issuer_name(x509, name);

Und schließlich sind wir bereit, die Unterzeichnung Prozess auszuführen. Wir nennen X509_sign mit dem Schlüssel, den wir früher erzeugt. Der Code dafür ist schmerzlich einfach:

X509_sign(x509, pkey, EVP_sha1());

Beachten Sie, dass wir die SHA-1 Hash-Algorithmus werden mit dem Schlüssel zu unterzeichnen. Dies unterscheidet sich von der mkcert.c Demo ich am Anfang dieser Antwort erwähnt, die verwendet MD5.


Wir haben jetzt ein selbst signiertes Zertifikat! Aber wir sind noch nicht fertig - wir diese Dateien auf die Festplatte schreiben müssen. Zum Glück OpenSSL hat uns auch dort mit den PEM_* Funktionen abgedeckt, die in openssl/pem.h deklariert sind. Die erste müssen wir ist PEM_write_PrivateKey für unsere privaten Schlüssel zu speichern.

FILE * f;
f = fopen("key.pem", "wb");
PEM_write_PrivateKey(
    f,                  /* write the key to the file we've opened */
    pkey,               /* our key from earlier */
    EVP_des_ede3_cbc(), /* default cipher for encrypting the key on disk */
    "replace_me",       /* passphrase required for decrypting the key on disk */
    10,                 /* length of the passphrase string */
    NULL,               /* callback for requesting a password */
    NULL                /* data to pass to the callback */
);

Wenn Sie nicht die privaten Schlüssel verschlüsseln wollen, dann übergeben Sie einfach NULL für den dritten und vierten Parameter oben. So oder so, werden Sie auf jeden Fall sicherstellen wollen, dass die Datei nicht die Welt lesbar ist. (Für Unix-Anwender bedeutet dies chmod 600 key.pem.)

Puh! Jetzt sind wir bis auf eine Funktion - wir müssen das Zertifikat auf die Festplatte schreiben. Die Funktion, die wir dafür brauchen, ist PEM_write_X509:

FILE * f;
f = fopen("cert.pem", "wb");
PEM_write_X509(
    f,   /* write the certificate to the file we've opened */
    x509 /* our certificate */
);

Und wir sind fertig! Hoffentlich wird die Informationen in dieser Antwort ist genug, um Ihnen eine grobe Vorstellung davon zu geben, wie alles funktioniert, obwohl wir haben kaum die Oberfläche von OpenSSL zerkratzt.

Für Interessenten an zu sehen, was die gesamten Code oben wie in einer realen Anwendung aussieht, habe ich zusammen eine Gist geworfen (geschrieben in C ++), die Sie sehen können hier .

Jede Chance, dies innerhalb Ihrer App über einen system Anruf zu tun? Mehrere gute Gründe, dies zu tun:

  • Lizenzierung: wohl die openssl ausführbaren Aufruf trennt sie von der Anwendung und kann bestimmte Vorteile bieten. Haftungsausschluss:. Konsultieren Sie einen Anwalt zu diesem

  • Dokumentation. OpenSSL kommt mit phänomenal Kommandozeilen-Dokumentation, die ein möglicherweise kompliziertes Werkzeug stark vereinfacht

  • Testbarkeit: Sie können OpenSSL Übung von der Kommandozeile, bis Sie genau wissen, wie Ihr certs erstellen. Es gibt ein Los von Optionen; erwarten von einem Tag auf diesem zu verbringen, bis Sie alle Details richtig zu machen. Danach ist es trivial den Befehl in Ihrer Anwendung.

  • einzuarbeiten

Wenn Sie die API verwenden, überprüfen Sie die Liste openssl-dev Entwickler auf www.openssl.org.

Viel Glück!

Sehr einfache Anleitung zum Erstellen von digitalen Zertifikaten http://publib.boulder.ibm.com/infocenter/rsthelp/v8r0m0/index.jsp?topic=/com.ibm.rational.test.lt.doc /topics/tcreatecertopenssl.html

Über diese Befehle aus dem Code ausführt bin ich nicht sicher.

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