2016-08-01 30 views
0

Ich muss wissen, welche CodierungC# ECDsaCng.SignData Signatur in OpenSSL verwenden?

https://msdn.microsoft.com/en-us/library/bb347054(v=vs.110).aspx

ECDsaCng.SignData Methode (Byte [])

ist für seine Byte-Array standardmäßig verwendet und wie es zu einem DER-Format von

akzeptiert konvertieren

https://www.openssl.org/docs/manmaster/crypto/i2d_ECDSA_SIG.html

so, dass ich meine C# erzeugt in OpenSSL mit der Methode ECDSA_do_verify ECSDA Signatur verifizieren kann.

Ich kenne seine SHA1 und ich weiß, wie dieser Digest zu laden, ich weiß nur nicht, was die Byte-Codierung für ECDsaCng.SignData-Methode, noch, wie es in DER-Format konvertieren, wenn ich das überhaupt tun muss .

+0

Sie haben DSA in C# und ECDSA in OpenSSL erwähnt; Welchen Algorithmus versuchen Sie eigentlich zu verwenden? Sie sind nicht die gleichen ... – bartonjs

+0

Ah sorry, ECDsaCng.SignData Methode (Byte []) ist, was bedeutet .. – Akumaburn

+0

Beachten Sie auch für jeden lesend dies die richtige Funktion ist SignHash, da ECDSA_do_verify einen bekannten Digest erwartet, und SignData wird re-Hash mit was auch immer der .NET-Standard ist und das hat mir so viel Ärger bereitet. Es gibt eine Implementierung von OpenSSL verify mit C# -Tasten, die ich in einer der Fragen unter meinem Profil gemacht habe, die Sie vielleicht auch auschecken möchten. Auch das kann hilfreich sein: http://stackoverflow.com/questions/24251336/import-a-public-key-from-irgendwo-else-to-cgnkey – Akumaburn

Antwort

1

Eine ECDSA-Signatur ist das Wertepaar (r, s).

Windows CNG emittiert dies als eine Verkettung der beiden Werte, und da .NET die Daten nicht neuinterpretiert, ist dies das de facto .NET-Format. (r ist die erste Hälfte des Arrays, s ist die zweite Hälfte)

OpenSSL erwartet eine DER-codierte Struktur von SEQUENCE (INTEGER (r), INTEGER (s)). Dies bedeutet locker { 0x30, payload_length, 0x02, r_length, r_bytes[0]...r_bytes[r_length-1], 0x02, s_length, s_bytes[0]...s_bytes[s_length-1] }; obwohl es etwas kniffliger ist als das, weil Füllbytes erforderlich sind, wenn r_bytes [0] oder s_bytes [0]> = 0x80 (da dies so aussieht, als wäre es eine negative Zahl).

Leider gibt es keinen allgemeinen DER-Encoder, der standardmäßig im Framework verfügbar ist.

Wenn Sie versuchen, unter Linux zu laufen, könnten Sie besser mit .NET Core bedient werden, da die ECDSA-Implementierung für Linux already does diese Datenübersetzung.

+0

Ist es genau die Hälfte des Arrays? Das heißt, R und S sind gleich groß? wenn nicht, wie bestimme ich, wann es (r oder s) beginnt und endet? – Akumaburn

+0

Nun, .NET Core interpretiert es als immer gleich groß (der Blob sollte also immer eine gerade Länge haben). Da Windows auch nicht genug Informationen hätte, um zu wissen, ob zusätzliche (oder defizitäre) Bytes von r oder s kommen, erscheint es logisch, dass sie eine starre Ausgabe verwenden. – bartonjs