Hallo zusammen,
ich hab es, ohne Erfolg, schon in einem andrem Forum versucht.
ich habe den Hash einer Datei und möchte diesen mit einem Zertifikat aus dem Zertifikatsspeicher signieren.
Den Hash (Byte Array) und das Zertifikat (X509Certificate2) bekomme ich übergeben.
Versucht habe ich es mit folgendem Code:
// http://blogs.msdn.com/b/shawnfa/archive/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures.aspx
RSACryptoServiceProvider rsa_msdn = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] signature_msdn = rsa_msdn.SignData(data, "SHA256");
if (rsa_msdn.VerifyData(data, "SHA256", signature_msdn))
{
Console.WriteLine("RSA-SHA256 signature verified");
Console.WriteLine(ConvertHexToString(signature_msdn));
}
else
{
Console.WriteLine("RSA-SHA256 signature failed to verify");
Console.WriteLine(ConvertHexToString(signature_msdn));
}
RSACryptoServiceProvider rsa_msdn2 = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] signature_msdn2 = rsa_msdn2.SignData(data, "SHA256");
if (rsa_msdn2.VerifyData(data, "SHA256", signature_msdn2))
{
Console.WriteLine("RSA-SHA256 signature verified");
Console.WriteLine(ConvertHexToString(signature_msdn2));
}
else
{
Console.WriteLine("RSA-SHA256 signature failed to verify");
Console.WriteLine(ConvertHexToString(signature_msdn2));
}
Hier bekomme ich den Fehler 'Ungültiger Algorithmus angegeben' beim 'SignData(data, "SHA256")'
Wenn ich den Key aus dem Store nicht verwende scheint es zu funktionieren:
RSACryptoServiceProvider rsa_msdn = new RSACryptoServiceProvider();
byte[] signature_msdn = rsa_msdn.SignData(data, "SHA256");
if (rsa_msdn.VerifyData(data, "SHA256", signature_msdn))
{
Console.WriteLine("RSA-SHA256 signature verified");
Console.WriteLine(ConvertHexToString(signature_msdn));
}
else
{
Console.WriteLine("RSA-SHA256 signature failed to verify");
Console.WriteLine(ConvertHexToString(signature_msdn));
}
Hat jemand eine Idee wie ich das Zertifikat für die Signatur verwenden kann?
Aendrew
Mal abgesehen davon, dass du wenig darüber schreibst, wie du das Certifikat lädst und was genau der Fehler ist, orakel ich mal ein wenig:
Zertifikate im Store haben zugriffsrechte - hast du geprüft, ob du es lesen kannst?
Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)
sorry, das hätte ich erwähnen sollen:
Wenn ich anstelle des SHA256 einen SHA1 verwende funktioniert alles bestens.
Aus diesem Grund gehe ich davon aus, dass das Zertifikat lesbar ist.
Spielt es dennoch einen Rolle wie das Zertifikat geladen wird?
Kurz noch zum Fehler:
Im Debugger wird nur die Information von oben angezeigt.
Führt man das Programm in der Commandline aus, dann bekommt man folgenden Fehler:> Fehlermeldung:
Unbehandelte Ausnahme: System.Security.Cryptography.CryptographicException: Ungültiger Algorithmus angegeben
bei System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
bei System.Security.Cryptography.Utils._SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 dwFlags)
bei System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, String str)
bei System.Security.Cryptography.RSACryptoServiceProvider.SignData(Byte[] buffer, Object halg)
bei PlainSignature.PlainSignature.SignPfx(Byte[] data, X509Certificate2 cert) in D:\PlainSignature\PlainSignature.cs:Zeile 741.
bei PlainSignature.PlainSignature.sign_Hash_RSA_SHA256_Certificate(Byte[] hashValue, String subjectCommonName, String outputFile) in D:\PlainSignature\PlainSignature.cs:Zeile 416.
bei PlainSignature.PlainSignature.Main(String[] args) in D:\PlainSignature\PlainSignature.cs:Zeile 162.
Du benutzt auch FW 3.5 SP1?
Denn erst ab dann kann der Rsacryptoserviceprovider etwas mit SHA256 anfangen.
sing RSACryptoServiceProvider for RSA-SHA256 signatures
Auch muss das Certificate PROV_RSA_FULL unterstützen, siehe Comment 4 im o.g. Post.
Auf meinem Windows 7 Rechner sind folgende Frameworks installiert:
Microsoft .NET Compact Framework 2.0 SP2
Microsoft .NET Compact Framework 3.5 (In der Registry ist Value bei 'SP' auf '1' gesetzt)
Microsoft .NET Framework 4 Client Profile
Microsoft .NET Framework 4 Client Profile DEU Language Pack
Microsoft .NET Framework 4 Extended
Microsoft .NET FRamework 4 Extended DEU Language Pack
Microsoft .NET Framework 4 Multi-Targeting Pack
Bei der Schlüsselverwendung im Zertifikat steht 'Digitale Signatur, Zugelassen (c0)'.
Damit sollte 'PROV_RSA_FULL' doch erfüllt sein, oder?
Weil in dem Post noch vom CSP gesprochen wurde:
Das Zertifikat befindet sich zusammen mit dem privaten Key im Store.
@Aendrew:
Deine Zertifikate muss mit "Microsoft Enhanced RSA and AES Cryptographic Provider" generiert werden um SHA256 als Hash Algorithmus zu nutzen. Z.B. erstelle ich eine Zertifikate mit openssl wie folgenden um SHA256 zu unterstützen.
openssl pkcs12 -export -in RCA.cert -inkey RCA.key -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out RCA.p12
Fragt dein CSP ob Sie SHA256 unterstüzen und für dich neue Zertifikate generieren.
Hi rongchaua,
du meinst es liegt am Zertifikat?
Ich hab heute gelernt, dass ich beim RSACryptoServiceProvider verschiedene CSPs verwenden kann.
Dieser muss beim Erzeugen festgelegt werden.
Wenn ich den aktuell verwendeten CSP auslese, dann erhalte ich den 'Microsoft Enhanced Cryptographic Provider v1.0' (Type 1).
Für die Signatur mit SHA256 müsste ich, wie du geschrieben hast, z.B. den 'Microsoft Enhanced RSA and AES Cryptographic Provider' (Type 24) verwenden.
Soweit, so gut aber wie bekomme ich es jetzt hin den richtigen (Type 24) CSP und das aus dem Store gelesene Zertifikat zu verwenden (also ohne es neu erstellen zu müssen)...
@Aendrew: Wenn du das Certificate Request an den Root CA schickst, generiert er für dich eine Zertifikate wie unten
openssl x509 -req -sha256 -CAcreateserial -in RCA.csr -days 365 -CA RootCA.cert -CAkey RootCA.key -out RCA.cert
Hiermit definiert der Root CA dass deine Zertifikate mit SHA256 angewendet werden kann. Du bekommst dann zurück deine Zertifkate-Datei (in diesem Beispiel ist RCA.cert). Wenn du deine Private Key mit der Zertifkate einbindest, musst du explicit mit den richtigen CSP (PROV_RVA_AES) einbinden
openssl pkcs12 -export -in RCA.cert -inkey RCA.key -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out RCA.p12
Du kannst aber auch den Inhalt der Zertifikate anschauen um zu prüfen ob es richtig war
openssl pkcs12 -info -nodes -in RCA.p12
oder
openssl x509 -in RCA.cert -text -noout
Daher schaust erstmal ob deine Zertifikate SHA256 unterstutzt und dann den Root CA kontaktieren.