2017-01-27 102 views
9

Mam działający kod, który tworzy poprawny podpis ciągu, jeśli załaduję certyfikat z pliku lub z magazynu bieżącego użytkownika. Jeśli jednak załaduję dokładnie ten sam certyfikat (ten sam plik .p12 i ten sam odcisk kciuka) z magazynu certyfikatów komputera, zachowuje się on inaczej. Po załadowaniu z tego sklepu sygnatury wygenerowane przez mój kod C# mają połowę długości (1024 bity zamiast 2048) i są niepoprawne. Wydaje się, że klucz prywatny ładuje się prawidłowo w obu przypadkach.Kryptografia: Dlaczego otrzymuję różne podpisy RSA w zależności od tego, z którego magazynu certyfikatów został załadowany certyfikat?

Dlaczego ładowanie certyfikatu jest ładowane od jakiejkolwiek różnicy do podpisu? I dlaczego podpis miałby być o połowę krótszy?

ładowane z CurrentUser:

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

(poprawne)

ładowane z LocalMachine:

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

(nieprawidłowe - i podkreślają kluczową 1024 nieco rozmiar i podpis długość)

Oto C# Używam:

 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

można sprawdzić wystawcy i numer seryjny zwracanego świadectwa? –

+0

@MaartenBodewes Emitent i numer seryjny są identyczne. – NickG

+0

Jedyne, co mogę myśleć to to, że klucz prywatny nie pasuje do certyfikatu. Może P12 nie został poprawnie skonstruowany. Trudno mi sobie wyobrazić, że certstore w Microsoft nie jest poprawne (z drugiej strony MS zaskoczyło mnie wcześniej). –

Odpowiedz

2

Okazuje się, że to coś wspólnego z formatem świadectwa używałem który stworzyłem z OpenSSL oraz fakt, że usługodawca kryptograficzny nie było zestaw. Komenda krytyczny jest numer 5 poniżej:

Oto polecenia I wykorzystywane do tworzenia certyfikatu pracy:

  1. Wygeneruj parę kluczy:

openssl genrsa -out private_key.pem 2048

  1. Wyodrębnij klucz publiczny:

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

  1. Tworzenie CSR certyfikat podpisywania żądać od klucza prywatnego:

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

  1. Generate self podpisany certyfikat :

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

  1. Tworzenie certyfikatu formatu PFX z określonym CSP:

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