关于C#:密码学:为什么我得到不同的RSA签名取决于从哪个证书存储加载证书?

Cryptography: Why am I getting different RSA signatures depending on which certificate store the certificate was loaded from?

我有一些工作代码,如果我从文件或当前用户的存储中加载证书,它将生成字符串的正确签名。但是,如果我从机器证书存储中加载完全相同的证书(相同的.p12和相同的指纹),它的行为会有所不同。当从该存储中加载时,由我的C代码生成的签名是长度的一半(1024位而不是2048位),并且是不正确的。在这两种情况下,私钥似乎都已正确加载。

为什么从哪个存储区加载证书与生成哪个签名有任何区别?为什么签名是长度的一半?

从当前用户加载:

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

(正确)

从本地计算机加载:

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

(不正确-请注意1024位密钥大小和签名长度)

这是我正在使用的C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        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();
      }


事实证明,这与我用OpenSSL创建的证书的文件格式有关,而且没有设置加密提供程序。关键命令是下面的数字5:

以下是我用来创建工作证书的命令:

  • 生成密钥对:
  • openssl genrsa -out private_key.pem 2048

  • 提取公钥:
  • openssl rsa -pubout -in private_key.pem -out public_key.pem

  • 从私钥创建CSR证书签名请求:
  • openssl req -new -key private_key.pem -out csr.csr

  • 生成自签名证书:
  • openssl x509 -req -days 1095 -in csr.csr -signkey private_key.pem -out certificate.crt

  • 使用指定的CSP创建pfx格式证书:
  • openssl pkcs12 -export -in certificate.crt -inkey private_key.pem -CSP"Microsoft Enhanced RSA and AES Cryptographic Provider" -out TEST_pfx.pfx