如何使用PEM格式的公钥创建证书对象?

时间:2019-11-10 19:19:24

标签: c# itext digital-signature x509certificate itext7

我想使用iText在PDF中嵌入签名的哈希值和公共内容。

根据iText 7中sign方法的参数,我需要通过证书链,

如何直接从公钥字符串创建此证书对象?

更新1 下面是小的C#代码。您可以看到我正在尝试从公共密钥获取x509证书。该证书将用于验证来自相应私钥的签名数据。还将用于将该公共证书和签名的哈希值嵌入PDF以进行数字签名。

在下面的代码中,我得到如下错误

错误:

'DigiSignDemo.exe'(CLR v4.0.30319:DigiSignDemo.exe):已加载'C:\ Users \ xposs \ source \ repos \ DigiSignDemo \ bin \ Debug \ itext.forms.dll'。跳过的加载符号。模块已优化,调试器选项“ Just My Code”已启用。 引发异常:mscorlib.dll中的“ System.Security.Cryptography.CryptographicException” mscorlib.dll中发生了类型为'System.Security.Cryptography.CryptographicException'的未处理异常 找不到请求的对象。

 public static readonly string publickey = @"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGhYfAvWxqIwsZsO1zUN
NyFT/3US7HGLXiW48NvYn2qNyn/9hm/BFWG901YoJAjlPTcNtMo1t8lUr2dRkc3l
8YyP8SetWKbznerQuXYBZZy31kp8u3Wj+zQSroZsFn69FoMAMWXqhkw9woFumINe
gw4sMtQ1S8CucX0uXJ4a2ElzoaUKp1M+MOCATDnmsXSyf/2/ERO71SpD+alDV2rE
m5DqvEnE0t27fm7PpNeCX0XEHRvx620LooGv1Co+0w5Au37sfSjOZp1B9V0n8KFR
6gLFY7mAZ1krZJscYgkNAPIz2QE6voBR8OVSHMnNcPH+0KLfGuNVHhaTyI4naPH+
0QIDAQAB
-----END PUBLIC KEY-----
";

  public static System.Security.Cryptography.X509Certificates.X509Certificate getPublicCertificate()
        {

//Here below I am getting error
                   X509Certificate2 clientCertificate =
    new X509Certificate2(Encoding.UTF8.GetBytes(publickey));

            return clientCertificate;
        }

2 个答案:

答案 0 :(得分:1)

您不能通过公共密钥创建证书。这就像问如何从方向盘上创建汽车一样……在成为汽车之前,您会错过很多其他东西。

鉴于您拥有SubjectPublicKeyInfo格式的RSA公钥,可以通过.p Core从.NET Core 3.0开始将其作为RSA密钥导入。

@for ($i = 0; $i < 10; $i++)
    @foreach($meals->where('meal_category_id', '=', $i) as $meal))
        {{ $meal }}
    @endforeach
@endfor

如果您不在.NET Core上,这要困难得多。有关更多信息,请参见How to load the RSA public key from file in C#How to get RSACryptoServiceProvider public and private key only in c#

答案 1 :(得分:0)

his answer中的

@bartonjs已经提到X509证书不仅仅是公钥。这里有一个说明显示了更多的内容。

为此,我们来看一下X509证书的规范RFC 5280。证书结构是在ASN.1中指定的,即使尚不知道,它也很容易遵循。

在这里,您将首先看到X509证书已签名:

Certificate  ::=  SEQUENCE  {
    tbsCertificate       TBSCertificate,
    signatureAlgorithm   AlgorithmIdentifier,
    signatureValue       BIT STRING  }

用于此签名的私钥可以再次与另一个证书(<发行者证书)的公钥关联,该证书可以再次使用与另一个证书的公钥关联的私钥进行签名。这产生了一系列证书,通常以使用该证书本身的私钥(自签名证书)签名的证书结尾。

为验证一个人是否信任证书中的信息,通常会遵循其发行者链,并检查一个人是否最终获得了某个证书,该证书来自一个人明确信任的少量证书。

其中的TBSCertificate包含要签名的信息。它指定为

TBSCertificate  ::=  SEQUENCE  {
    version         [0]  EXPLICIT Version DEFAULT v1,
    serialNumber         CertificateSerialNumber,
    signature            AlgorithmIdentifier,
    issuer               Name,
    validity             Validity,
    subject              Name,
    subjectPublicKeyInfo SubjectPublicKeyInfo,
    issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
    subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
    extensions      [3]  EXPLICIT Extensions OPTIONAL
    }

这里特别是主题名称,问题名称和序列号。主题名称描述此证书的持有者,颁发名称是颁发者证​​书的主题名称,序列号是颁发者在签署证书时确定的唯一编号。

有效间隔表示证书有效的预期时间跨度。

然后最终是SubjectPublicKeyInfo,其中包含证书的公共密钥。

最后,扩展是一个可选集合,其中包含额外的信息,例如证书(及其私钥的允许使用情况)以及可以检索证书吊销信息的URL。


如您所见,您不能仅仅基于公钥来简单地证书。您可以单独基于它创建 a 证书,但是不要期望任何人信任它。