Encryption 如何手动计算和验证证书签名请求的签名 我已经创建了一个密钥对

Encryption 如何手动计算和验证证书签名请求的签名 我已经创建了一个密钥对,encryption,openssl,public-key-encryption,public-key,pki,Encryption,Openssl,Public Key Encryption,Public Key,Pki,openssl genrsa-out test1 2048 然后使用该密钥创建了一个证书签名请求 openssl-req-new-key test1-subc”/CN=foo“-out foo.csr 使用openssl req-in foo.csr-text 它包含我生成的密钥对的公钥 Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:ca

openssl genrsa-out test1 2048

  • 然后使用该密钥创建了一个证书签名请求
openssl-req-new-key test1-subc”/CN=foo“-out foo.csr

  • 使用
    openssl req-in foo.csr-text
    • 它包含我生成的密钥对的公钥

            Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
            Modulus:
                00:ca:c5:29:98:08:05:30:30:03:08:eb:23:c2:af:
                3e:2e:2d:dc:11:96:cb:2f:d1:1f:7f:41:a4:00:13:
                8a:ee:4b:36:5b:f2:c1:d1:0f:8b:27:11:34:08:bd:
                4d:df:7e:6d:7a:d7:f9:dd:ea:62:ad:fa:8f:8c:eb:
                47:5f:55:82:2c:13:c2:11:41:12:b9:87:0b:3d:08:
                86:1b:ad:71:16:89:1c:fa:07:4a:86:8f:80:a9:99:
                37:f7:e2:d4:d3:d8:b2:5f:7f:c9:05:51:73:f0:c8:
                59:ec:c3:09:a2:03:a5:6e:ec:8b:d9:9c:11:de:d3:
                df:55:a5:3f:0c:36:d6:93:8a:70:a0:b9:61:cd:c9:
                4a:09:ad:f7:3e:fd:ce:6f:5c:bb:00:69:e9:3b:3d:
                85:3b:01:1d:8f:6a:a7:d4:61:f9:b5:07:1e:90:ed:
                ab:3b:41:cc:db:e8:a0:e7:88:b7:77:35:66:30:b7:
                a6:cd:ea:d6:12:f5:ef:82:63:e9:46:29:2e:7c:10:
                0e:32:fd:04:2d:cd:62:0e:4b:74:46:f7:fd:f6:4a:
                8d:fb:82:9d:37:11:50:ea:9f:f0:d6:64:2b:50:a4:
                f0:18:6e:81:28:11:04:db:2a:0a:f7:b1:70:c5:78:
                fe:ed:e3:55:2c:64:f4:a5:a0:96:f5:11:3a:27:2c:
                5a:51
            Exponent: 65537 (0x10001)
      
    • 我在创建CSR时提供的主题属性

              Subject: CN=foo
      
    • 数字签名信息

      签名算法:SHA256WithRSA加密 92:b0:82:a5:aa:98:4a:62:5a:84:8a:15:5c:6f:48:dc:e3:ec: 7f:d5:04:e8:c1:47:55:3c:b3:57:84:16:ff:5a:0d:29:2c:16: f2:cc:0c:18:c3:1f:d5:e1:57:3a:dd:8b:b1:c6:92:c3:fe:cb: 2b:9d:7d:79:d5:64:eb:31:00:8b:5e:77:48:ce:66:6f:dd:7b: 71:41:f9:aa:6e:ea:ea:59:e0:cd:f8:db:a9:13:18:d2:2a:fc: 12:25:b3:01:44:0c:b1:02:f7:1a:0f:d0:07:04:1d:9f:6f:a1: 58:91:87:25:4a:d6:47:a6:b5:4e:3c:a1:fd:b6:6c:c3:96:16: c1:ab:00:d2:4c:95:ee:2c:01:2d:cf:0e:d0:62:1b:4f:0e:34: e3:e8:85:50:63:74:eb:1f:ac:95:30:d4:df:43:7f:58:11:90: 35:29:9d:85:94:dc:c8:c2:29:81:46:71:20:62:9c:9c:f8:ef: 埃德:bc:8b:e3:d5:41:b3:14:f7:43:c6:b2:74:c2:22:06:a2:af: 88:68:2e:67:c4:de:ed:61:37:41:d6:df:8a:76:7d:42:5d:98: d3:c9:19:8b:1d:26:73:92:95:0f:ba:c1:78:3a:55:87:e0:3e: 16:13:34:6e:21:13:b9:da:b8:66:f3:0a:ec:79:ae:1a:95:6c: 04:cf:b8:b5

以下是我的疑问:

  • 计算签名时考虑了哪些数据字段
  • 我们可以手动创建签名并用CSR中提到的签名进行验证吗

  • 除了签名算法和签名之外,计算签名的数据几乎是CSR中的所有数据。这称为中的
    certificationRequestInfo

    第二个问题:我们如何验证签名

    简短的回答:让
    openssl
    为您做这件事

    到目前为止,最简单的方法是要求
    openssl
    本身验证它:

    $ openssl genrsa -out test.key 2048
    $ openssl req -new -key test.key -subj "/CN=foo" -out foo.csr
    $ openssl req -in foo.csr -verify -noout
    verify OK
    
    完成了


    冗长(且乏味)的答案:手动完成

    好的,所以你真的想手动操作。让我们试一试

    鉴于上述情况,我们首先需要从CSR中提取所需的信息。卸下ASN.1结构,我们得到:

    $ openssl asn1parse -i -in foo.csr 
        0:d=0  hl=4 l= 595 cons: SEQUENCE          
        4:d=1  hl=4 l= 315 cons:  SEQUENCE          
        8:d=2  hl=2 l=   1 prim:   INTEGER           :00
       11:d=2  hl=2 l=  14 cons:   SEQUENCE          
       13:d=3  hl=2 l=  12 cons:    SET               
       15:d=4  hl=2 l=  10 cons:     SEQUENCE          
       17:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
       22:d=5  hl=2 l=   3 prim:      UTF8STRING        :foo
       27:d=2  hl=4 l= 290 cons:   SEQUENCE          
       31:d=3  hl=2 l=  13 cons:    SEQUENCE          
       33:d=4  hl=2 l=   9 prim:     OBJECT            :rsaEncryption
       44:d=4  hl=2 l=   0 prim:     NULL              
       46:d=3  hl=4 l= 271 prim:    BIT STRING        
      321:d=2  hl=2 l=   0 cons:   cont [ 0 ]        
      323:d=1  hl=2 l=  13 cons:  SEQUENCE          
      325:d=2  hl=2 l=   9 prim:   OBJECT            :sha256WithRSAEncryption
      336:d=2  hl=2 l=   0 prim:   NULL              
      338:d=1  hl=4 l= 257 prim:  BIT STRING        
    
    这是一个结构化的CertificationRequest,定义如下:

    DER编码ASN.1格式的
    certificationRequestInfo
    (结构细节请参见RFC)使用
    signatureAlgorithm
    中描述的算法和私钥进行签名,以生成
    签名


    让我们从CSR中提取我们需要的所有部分。
    strparse
    值是要导出的偏移量,这是上面输出中每行的第一个数字

    # Extract the certificationRequestInfo (data to be signed)
    $ openssl asn1parse -in foo.csr -strparse 4 -out info.der
    
    # Extract the public key.
    $ openssl req -pubkey -in foo.csr -noout -out pub.pem
    
    # Alternatively, you can use:
    $ openssl asn1parse -in foo.csr -strparse 27 -out tmp.der
    $ openssl rsa -pubin -inform DER -in tmp.der -out pub.pem
    
    # Extract the raw signature bytes:
    $ openssl asn1parse -in foo.csr -strparse 338 -out sig.raw
        0:d=0  hl=2 l=  70 cons: cont [ 3 ]        
    Error in encoding
    139935063934272:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:
    
    忽略最后一个错误,这是因为提取的数据是原始签名字节,而不是ASN.1编码的
    openssl
    仍然很高兴地将它写到文件中

    我们现在有以下文件:

    • info.der
      :已签名的der编码数据
    • pub.pem
      :CSR请求者的公钥
    • sig.raw
      :CSR中包含的签名

    让我们使用公钥验证RSA签名(因为签名算法就是这么说的),并提取原始哈希:

    $ openssl rsautl -verify -pubin -inkey pub.pem -in sig.raw -out hash.der
    $ openssl asn1parse -i -in hash.der -inform DER
        0:d=0  hl=2 l=  49 cons: SEQUENCE          
        2:d=1  hl=2 l=  13 cons:  SEQUENCE          
        4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
       15:d=2  hl=2 l=   0 prim:   NULL              
       17:d=1  hl=2 l=  32 prim:  OCTET STRING      [HEX DUMP]:192E0909DABC7454006628AA3F7FB009AFA62A17A44908CAE5E166E528DCDD11
    
    它没有失败,因此我们已经知道公钥与用于对数据签名的私钥相匹配

    最后一部分,长的
    八位字节字符串
    是CSR请求程序计算的消息原始散列:

    192e0909dabc7454006628aa3f7fb009afa62a17a44908cae5e166e528dcdd11
    

    让我们计算
    certificationRequestInfo
    sha256
    散列(再次:因为签名算法告诉我们这样做):

    $ sha256sum info.der 
    192e0909dabc7454006628aa3f7fb009afa62a17a44908cae5e166e528dcdd11  info.der
    
    耶!哈希值等于从签名中提取的哈希值


    哈希匹配,签名由CSR中列出的公钥对应的私钥签名这是一个有效的CSR


    完成了!看,我说过这会很乏味。

    非常感谢,你的解释令人惊讶,现在整个概念都清楚了。感谢你提供的详细步骤和命令,我可以使用这些命令来了解expore。再次感谢,不用担心。作为练习,您可以研究证书(与CSR相反)是如何构造的,并使用颁发者的公钥验证其签名。这是一组类似的步骤,只是不同的ASN.1结构,当然,颁发者的密钥来自颁发者的证书(根证书或中间证书)。谢谢。。我会的。同时,我有一个跟进问题/请检查是否可能
    $ sha256sum info.der 
    192e0909dabc7454006628aa3f7fb009afa62a17a44908cae5e166e528dcdd11  info.der