2017-04-19 4 views
5

Ich habe ein öffentliches/privates Schlüsselpaar (Elliptic Curve) mit SecKeyGeneratePair erstellt.Generieren CSR von SecKey mit OpenSSL

Wie kann ich die Instanzen SecKey verwenden, um eine CSR mit OpenSSL in Swift zu generieren?

+1

[Verwandte] (https://stackoverflow.com/questions/13456237/generating-an-openssl-certificate-signing-request-in-ios-with-keychain-stored-ke?rq=1), aber nicht in Schnell. –

Antwort

1

Soweit ich sagen kann, hat Apples eigenes Sicherheitsframework derzeit keine API, die für das Generieren von CSRs verfügbar ist. Es ist technisch OpenSSL verpackt; Wenn Sie also OpenSSL haben (ich persönlich bevorzuge LibreSSL, macht libtls das Leben leichter).

Als Alternative auch Commoncrypto verwenden können, die meine Antwort nicht abdecken, aber es gibt viele, viele Beispiele gibt

lässt So gehen Sie durch die Schritte, herauszufinden, wie dies zu tun. Ich fand, dass der einfachste Weg, mit OpenSSL zu arbeiten, ist, die Dokumentation vollständig zu ignorieren und direkt zum Lesen der Quelle zu gehen.

Um das zu erreichen, was wir brauchen, müssen wir die folgenden zwei Befehle zu 'Wiederholungs':

openssl ecparam -out server.key -name prime256v1 -genkey

openssl req -new -key server.key -out server.csr

Wichtiger Hinweis: eine sichere Kurve wählen Seien Sie sicher. Verwenden Sie openssl ecparam -list_curves, um eine Liste der unterstützten Kurven nach Ihrer Version von openssl zu erhalten. Read more

Schritt 1 Generieren der Schlüssel

ecparam uns sagt, wir zuerst in sslsource/apps/openssl/ecparam.c suchen.

Die Quelle gibt uns 3 Schritte: BIO zum Schreiben einrichten, Gruppenparameter einrichten und schließlich den Schlüssel generieren.

Schritt 2 die CSR generieren

Nach den gleichen Prinzipien, sondern diese in req.c und einige Code in apps.c Suche Zeit, die einige Standardcode in req.c

verwendet wird, enthält ich diese Methode verwendet, um ein rohes zu erstellen aber funktionierender proof of concept, der in swift läuft, kannst du es hier auf github ausprobieren: CertificateTool Der Code wird auf jedem System laufen, auf dem du die swift4 + toolchain und eine Version von openSSL kompilieren kannst.

Edit:

die EG-Geheimschlüssel generieren:

// 
// ECKey.swift 
// CertificateToolPackageDescription 
// 
// Created by Antwan van Houdt on 10/01/2018. 
// 
import CLibreSSL 

public class ECKey { 
    internal let secretKey: OpaquePointer 
    private let group: OpaquePointer 

    public init() { 
     group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1) 
     EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE) 
     EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_COMPRESSED) 

     secretKey = EC_KEY_new() 
     EC_KEY_set_group(secretKey, group) 
     EC_KEY_generate_key(secretKey) 
    } 

    deinit { 
     EC_KEY_free(secretKey) 
     EC_GROUP_free(group) 
    } 
} 

die Signaturanforderung erstellen:

// 
// CertificateRequest.swift 
// CertificateToolPackageDescription 
// 
// Created by Antwan van Houdt on 10/01/2018. 
// 
import CLibreSSL 

public enum NIDType: String { 
    case email = "emailAddress" 
    case hostName = "CN" 
    case organizationalUnit = "OU" 
    case organization  = "O" 
    case city  = "L" 
    case state  = "ST" 
    case countryCode = "C" 
} 

public class CertificateSigningRequest { 
    private let request: UnsafeMutablePointer<X509_REQ> 
    private let key:  ECKey 
    private let name: UnsafeMutablePointer<X509_NAME> 

    public init(key: ECKey, email: String, hostName: String, organizationalUnit: String, organization: String, countryCode: String, state: String, city: String) { 
     request = X509_REQ_new() 
     self.key = key 

     name = X509_NAME_new() 
     X509_REQ_set_version(request, 2) 

     self.add(name: email, type: .email) 
     self.add(name: hostName, type: .hostName) 
     self.add(name: organizationalUnit, type: .organizationalUnit) 
     self.add(name: organization, type: .organization) 
     self.add(name: countryCode, type: .countryCode) 
     self.add(name: city, type: .city) 
     self.add(name: state, type: .state) 

     X509_REQ_set_subject_name(request, name) 

     self.setPublicKey() 
    } 

    deinit { 
     X509_REQ_free(request) 
     X509_NAME_free(name) 
    } 

    private func add(name: String, type: NIDType) { 
     var buff = Array(name.utf8) 
     X509_NAME_add_entry_by_NID(self.name, OBJ_txt2nid(type.rawValue), MBSTRING_UTF8, &buff, Int32(buff.count), 0, 0) 
    } 

    private func setPublicKey() { 
     let certKey = EVP_PKEY_new() 
     EVP_PKEY_set1_EC_KEY(certKey, key.secretKey) 

     X509_REQ_set_pubkey(request, certKey) 
     X509_REQ_sign(request, certKey, EVP_sha256()) 

     EVP_PKEY_free(certKey) 
    } 
} 

Hinweis Dieser Code keine BIO bezogenen Funktionen enthält (noch) um die PEM-Daten in eine Datei oder in einen Datenpuffer zu schreiben, aber sie sind wirklich einfach hinzuzufügen.

Haftungsausschluss: Ich bin kein professioneller Kryptograf, noch kenne ich alle Ins und Outs der OpenSSL-API. Ich kann nicht garantieren, dass der von mir bereitgestellte Code eine 100% korrekte Implementierung ist. Seien Sie immer auf der Hut vor Code, insbesondere Krypto-Code, der aus dem Internet heruntergeladen wurde.

Verwandte Themen