Criptografia: Por que estou recebendo assinaturas RSA diferentes dependendo de qual repositório de certificados o certificado foi carregado?

8

Eu tenho algum código de trabalho que produz uma assinatura correta de uma string se eu carregar um certificado de um arquivo ou do armazenamento do usuário atual. No entanto, se eu carregar exatamente o mesmo certificado (mesmo .p12 e mesma impressão digital) do armazenamento de certificados do computador, ele se comportará de maneira diferente. Quando carregado a partir desse armazenamento, as assinaturas geradas pelo meu código c # são metade do comprimento (1024 bits em vez de 2048) e estão incorretas. A chave privada parece estar sendo carregada corretamente em ambos os casos.

Por que o armazenamento no qual o certificado é carregado faz alguma diferença na qual a assinatura é gerada? E por que a assinatura teria metade do tamanho?

Carregado de CurrentUser:

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

(correto)

Carregado de LocalMachine:

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

(incorreto - e observe o tamanho da chave de 1024 bits e o tamanho da assinatura)

Aqui está o c # que estou usando:

        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();
      }
    
por NickG 27.01.2017 в 12:01
fonte

1 resposta

3

Acontece que tem algo a ver com o formato de arquivo do certificado que eu estava usando, o qual eu criei com o OpenSSL e com o fato de que o provedor de criptografia não estava configurado. O comando crítico é o número 5 abaixo:

Aqui estão os comandos que usei para criar o certificado de trabalho:

  1. Gere um par de chaves:

openssl genrsa -out private_key.pem 2048

  1. Extraia a chave pública:

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

  1. Crie uma solicitação de assinatura de certificado de CSR a partir da chave privada:

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

  1. Gerar um certificado autoassinado:

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

  1. Crie um certificado de formato PFX com o CSP especificado:

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

    
por NickG 30.01.2017 / 15:06
fonte