Wie kann ich eine IIS7-SSL-Erneuerungs-CSR mit OpenSSL überprüfen / lesen?

10

Ich habe das Privileg, ~ 5 SSL-CSRs pro Woche zu verarbeiten und deren Gültigkeit zu überprüfen, bevor ich sie zur Bearbeitung an unsere Zertifizierungsstelle weitergebe. Ich verwende OpenSSL auf einem Ubuntu-Computer, um zu überprüfen, ob sie gültig sind, und teste Dinge wie den richtigen OU-Namen, einen vernünftigen CN, eine Schlüsselgröße> = 2048 Bit usw., da unsere Anforderungen manchmal falsch sind.

Neulich erhielt ich eine Verlängerungsanforderung von einem IIS7-Computer. Ich kann mit OpenSSL überhaupt nicht herausfinden, wie ich das lesen soll. Es ist gültig, da meine Zertifizierungsstelle es akzeptiert hat ...

'file (1)' besagt, dass es sich um einen "RFC1421-Sicherheitszertifikatsignaturanforderungstext" handelt, der für ~ 50% der CSRs, die ich hier habe, angegeben ist (der Rest ist "PEM-Zertifikatanforderung").

$ head iis7rcsr
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIQsQYJKoZIhvcNAQcCoIIQojCCEJ4CAQExCzAJBgUrDgMCGgUAMIIJegYJKoZI
hvcNAQcBoIIJawSCCWcwggljMIIIzAIBADCB2zELMAkGA1UEBhMCTloxDTALBgNV
BBEMBDkwNTQxDjAMBgNVBAgMBU90YWdvMRAwDgYDVQQHDAdEdW5lZGluMRwwGgYD
...
...

openssl req, der CSRs (PKCS # 10) liest, versteht es nicht ...

$ openssl req -in iis7rcsr -text
unable to load X509 request
5156:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1316:
5156:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=X509_REQ_INFO
5156:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:748:Field=req_info, Type=X509_REQ
5156:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_oth.c:83:

Dieser Artikel von Andreas Klein in den MSDN-Blogs schlägt vor, dass IIS7-Erneuerungs-CSRs ein PKCS # 7-Container sind, mit einer CSR und einer Signatur, die auf dem aktuellen Zertifikat basiert ... aber ich kann sie immer noch nicht lesen.

$ openssl pkcs7 -in iis7rcsr -text
unable to load PKCS7 object
6581:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:650:Expecting: PKCS7

Ich kann 'openssl base64' verwenden, um die Datei zu dekodieren, und in der resultierenden Binärdatei sehe ich Zeichenfolgen, die wie die CSR aussehen, und einige CA-Referenzen, die von einer Signatur stammen müssen, die auf dem alten Zertifikat basiert. Die Idee des Containers (CSR, Signatur) klingt also plausibel.

Aber ich kann immer noch keinen Weg finden, die CSR zu lesen, die da drin ist! Ich habe viele Dinge ausprobiert, ich werde die Details hier nicht auflisten, aber hier sind die Höhepunkte der Variationen, die ich versucht habe: pkcs12 pkcs7 PEM DER req x509 verifizieren ...

Ich kann den CSR selbst hier leider nicht posten. Kann mir jemand helfen, eine Möglichkeit zum Lesen / Überprüfen dieser Datei zu finden?

Jim Cheetham
quelle
Enthält die Anfrage zufällig Attribute, die nach einem alternativen Betreff suchen?
Shane Madden
Ich bezweifle es - es ist für einen internen Server mit einem einzigen Namen. Natürlich haben die Zertifikate, die wir zurückerhalten, normalerweise ein SAN-Feld mit "www". gewaltsam eingefügt, aber damit leben wir!
Jim Cheetham
certutil von einem Windows-Computer liest dieses Zertifikat und beschreibt es als PKCS7-Nachricht mit einer PKCS10-Zertifikatsanforderung (mit x509-Zertifikat von der alten Zertifizierungsstelle) und einer Zertifikatskette mit einem weiteren x509-Zertifikat. 'certutil -split' bricht diese Teile aus, und Blob0_1.p10 ist die CSR, die ich im DER-Format finden möchte. Also komme ich näher ... und ja, die Anfrage enthält ein SAN-Feld, das wahrscheinlich das Ergebnis des erzwungenen Einfügens von "www" ist. als wir letztes Jahr das Originalzertifikat bekamen ...
Jim Cheetham
1
openssl asn1parsekann die Anfrage lesen und von dort aus kann ich die normale CSR extrahieren. Ich kann mich noch nicht selbst beantworten (habe es zu schnell gelöst), daher werde ich die Frage mit der Lösung aktualisieren und sie dann morgen beheben :-)
Jim Cheetham
Schön, guter Fund!
Shane Madden

Antworten:

8

Die Struktur dieser IIS7-Erneuerungsanforderung ist eigentlich recht elegant. Es scheint von der Prämisse auszugehen, dass, da dies eine Anforderung zum Erneuern eines aktuellen Zertifikats ist, nachgewiesen werden muss, dass die Anforderung vom richtigen Host stammt - dh der Host, der das aktuelle Zertifikat tatsächlich verwendet und das zugehörige private besitzt Schlüssel. In der Internet-Welt beweisen Sie, dass Sie Verlängerungen für ein Zertifikat beantragen dürfen, indem Sie sich bei Ihrer Zertifizierungsstelle als ursprünglicher Benutzer authentifizieren, anstatt eine signierte CSR zu erstellen.

Um das Recht zu beweisen, eine Verlängerungsanforderung zu stellen, erstellt IIS7 eine normale CSR (PKCS # 10-Objekt), signiert sie und signiert das Zertifikat des Schlüssels, der sie signiert hat.

  • IIS7-Erneuerungs-CSR
    • PKCS # 7-Daten
      • PKCS # 10-Daten (die normale CSR)
    • Normales Serverzertifikat
    • CA-Daten ausgeben
    • RSA-Signatur (nehme ich an)

Verwenden Sie openssl asn1parse -in iis7rcsr -idiese Option, um die Struktur der Datei anzuzeigen und diese mit normalen CSRs zu vergleichen. Sie sollten am Anfang einen OCTET STRING in einem Objekt mit der Bezeichnung ": pkcs7-data" sehen, das Sie extrahieren müssen, um die CSR zu erhalten.

$ openssl asn1parse -in iis7rcsr -i
0:d=0  hl=4 l=4273 cons: SEQUENCE          
4:d=1  hl=2 l=   9 prim:  OBJECT            :pkcs7-signedData
15:d=1  hl=4 l=4258 cons:  cont [ 0 ]        
19:d=2  hl=4 l=4254 cons:   SEQUENCE          
23:d=3  hl=2 l=   1 prim:    INTEGER           :01
26:d=3  hl=2 l=  11 cons:    SET               
28:d=4  hl=2 l=   9 cons:     SEQUENCE          
30:d=5  hl=2 l=   5 prim:      OBJECT            :sha1
37:d=5  hl=2 l=   0 prim:      NULL              
39:d=3  hl=4 l=2426 cons:    SEQUENCE          
43:d=4  hl=2 l=   9 prim:     OBJECT            :pkcs7-data
54:d=4  hl=4 l=2411 cons:     cont [ 0 ]        
58:d=5  hl=4 l=2407 prim:      OCTET STRING      [HEX DUMP]:3082096330820...

Um die tatsächliche PKCS # 10-CSR hier rauszuholen, benötigen wir die Offset-Nummer "58" in diesem Beispiel. Dann können wir diesen Offset verwenden, um die Binärversion dieses Objekts zu extrahieren: -

$ openssl asn1parse -in iis7rcsr -strparse 58 -out thecsr -noout

Als nächstes können wir diese Ausgabedatei 'thecsr' mit lesen openssl reqund dabei daran denken, das Eingabeformat DER anzugeben.

$ openssl req -in thecsr -inform DER -text -noout
Certificate Request:
Data:
    Version: 0 (0x0)
    Subject: (normal CSR Subject: line, censored)
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
...

Ich kann all dies in einer Befehlszeile ohne temporäre Dateien zusammenfassen (aber leider 2 Lesevorgänge des ursprünglichen Zertifikats), solange ich Linux verwenden kann, um openssl /proc/self/fd/zu täuschen (es werden native Tricks mit Dateideskriptoren für die Kennwortbehandlung ausgeführt, aber nicht normale Ausgabe).

$ openssl asn1parse -in iis7rcsr -strparse $(openssl asn1parse -in iis7rcsr | grep -A2 ':pkcs7-data'|tail -1|cut -d: -f1) -out /dev/stdout -noout | openssl req -inform DER -noout -text

Certificate Request:
Data:
    Version: 0 (0x0)
    Subject: (Subject: line censored again)
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
        RSA Public Key: (1024 bit)
            Modulus (1024 bit):
...

Diese lange Befehlszeile entspricht direkt der einfachen openssl req -in non-iis7rcsr -noout -text, die ich normalerweise benutze :-)

Jim Cheetham
quelle
Es ist CMC tools.ietf.org/html/rfc5272#section-3.2
Daniel Fisher lennybacon
2

Vielen Dank an Jim für diese hervorragenden Informationen, die sehr hilfreich waren. Ich hatte genau das gleiche Problem beim Versuch, ein w2008 / IIS7-Serverzertifikat zu erneuern.

Ich würde nur eins hinzufügen. Möglicherweise können Sie die CSR im P10-Format direkt mit dem folgenden Befehl certutil -split iis7rcsr extrahieren : (iis7rcsr ist die CSR-Datei, die Sie über den IIS-Manager erhalten). Die CSR wird dann in eine Datei mit dem Namen blob0_1.p10 Es ist im Binärformat (DER) extrahiert. Möglicherweise müssen Sie sie in base64 mit dem folgenden Befehl codieren: certutil -encode blob0_1.p10 finalcsr.csr

Es gibt jedoch ein letztes Problem. Beim Speichern des CSR-Inhalts mit openssl stellte ich dann fest, dass der Erneuerungsprozess automatisch die Verwendung eines 1024-Bit-Schlüssels erzwang (obwohl der ursprüngliche private Schlüssel, der auf dem Server für das Serverzertifikat erstellt wurde, 2048 Bit lang war). Es scheint, dass Sie die Verwendung von 2048-Bit-Schlüsseln mithilfe des Erneuerungsprozesses von IIS7 nicht erzwingen können.

Die einzig gute Option scheint darin zu bestehen, einen neuen Schlüssel / ein neues Zertifikat zu erstellen und den Erneuerungsprozess nicht zu verwenden.

Florent Vélu
quelle