2017-01-27 2 views
9

Ich habe einige Arbeitscode, der eine korrekte Signatur einer Zeichenfolge erzeugt, wenn ich ein Zertifikat aus einer Datei oder aus dem Speicher des aktuellen Benutzers laden. Wenn ich jedoch das exakt gleiche Zertifikat (derselbe .p12 und derselbe Fingerabdruck) vom Computer-Zertifikatspeicher laden, verhält es sich anders. Wenn sie von diesem Speicher geladen werden, sind die von meinem C# -Code erzeugten Signaturen die halbe Länge (1024 Bits anstelle von 2048) und sind inkorrekt. Der private Schlüssel scheint in beiden Fällen ordnungsgemäß geladen zu werden.Kryptographie: Warum erhalte ich unterschiedliche RSA-Signaturen, abhängig davon, aus welchem ​​Zertifikatspeicher das Zertifikat geladen wurde?

Warum wird aus welchem ​​Speicher, aus dem das Zertifikat geladen wird, unterschieden, welche Signatur generiert wird? Und warum sollte die Unterschrift die halbe Länge haben?

von Current Loaded:

Thumbprint: FBBE05A1C5F2AEF637CDE20A7985CD1011861651 
Has private key:True 
rsa.KeySize (bits) =2048 
Signature Length (bits): 2048 
Signature: kBC2yh0WCo/AU8aVo+VUbRoh67aIJ7SWM4dRMkNvt... 

(korrekt)

von Localmachine Loaded:

Thumbprint: FBBE05A1C5F2AEF637CDE20A7985CD1011861651 
Has private key: True 
rsa.KeySize (bits) = 1024 
Signature Length (bits): 1024 
Signature: RijmdQ73DXHK1IUYkOzov2R+WRdHW8tLqsH.... 

(falsch - und beachten Sie die 1024-Bit-Schlüsselgröße und Signaturlänge)

Hier ist der C# Ich verwende:

 string s = "AE0DE01564,1484821101811,http://localhost:8080/example_site/CallBack"; 

     var inputData = Encoding.UTF8.GetBytes(s); 

     var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 

     string thumbprint = CleanThumbPrint("fb be 05 a1 c5 f2 ae f6 37 cd e2 0a 79 85 cd 10 11 86 16 51"); 
     X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false); 

     // TODO: close store. 
     X509Certificate2 certificate = null; 

     Console.WriteLine("Cert count: " + col.Count); 
     if (col.Count == 1) 
     { 
      certificate = col[0]; 
      RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)col[0].PrivateKey; 

      // Force use of the Enhanced RSA and AES Cryptographic Provider with openssl-generated SHA256 keys 
      var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo; 

      var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, rsa.CspKeyContainerInfo.KeyContainerName); 

      rsa = new RSACryptoServiceProvider(cspparams); 
      Console.WriteLine("Name: " + certificate.SubjectName.Name); 
      Console.WriteLine("Thumbprint: " + certificate.Thumbprint); 
      Console.WriteLine("Has private key: " + certificate.HasPrivateKey); 
      Console.WriteLine("Sig algorithm: " + certificate.SignatureAlgorithm); 
      Console.WriteLine("rsa.KeySize (bits) =" + rsa.KeySize); 

      var sha256 = CryptoConfig.CreateFromName("SHA256"); 
      byte[] signature = rsa.SignData(inputData, sha256); 

      Console.WriteLine("Signature Length (bits): " + signature.Length * 8); 
      Console.WriteLine("Signature: " + System.Convert.ToBase64String(signature)); 
      Console.WriteLine(); 
     } 
+1

Könnten Sie den Aussteller und die Seriennummer des Zertifikats zurück überprüfen? –

+0

@MaartenBodewes Aussteller und Seriennummer sind identisch. – NickG

+0

Das einzige, was mir einfällt, ist, dass der private Schlüssel nicht mit dem Zertifikat übereinstimmt. Vielleicht wurde der P12 nicht richtig aufgebaut. Ich kann mir kaum vorstellen, dass der certstore in Microsoft nicht korrekt ist (andererseits hat mich MS vorher schon erstaunt). –

Antwort

2

Es stellt sich heraus, es war etwas, mit dem Dateiformat des Zertifikats zu tun war ich mit, die ich mit OpenSSL und die Tatsache geschaffen, dass der Krypto-Anbieter nicht einstellen. Der kritische Befehl Nummer 5 unter:

Hier sind die Befehle, die ich verwenden, um das Arbeits Zertifikat zu erstellen:

  1. generiert ein Schlüsselpaar:

openssl genrsa -out private_key.pem 2048

  1. Den öffentlichen Schlüssel extrahieren:

openssl rsa -pubout -in private_key.pem -out public_key.pem

  1. erstellen CSR Zertifikatsignieranforderung aus privaten Schlüssel:

openssl req -new -key private_key.pem -out csr.csr

  1. Generieren Sie ein selbst signiertes Zertifikat :

openssl x509 -req -days 1095 -in csr.csr -signkey private_key.pem -out certificate.crt

  1. erstellen PFX-Format Zertifikat mit dem CSP angegeben:

openssl pkcs12 -export -in certificate.crt -inkey private_key.pem -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out TEST_pfx.pfx

Verwandte Themen