数字签名手动哈希验证

数字签名手动哈希验证

我正在尝试学习 PKI,我想做一个测试,通过比较哈希值来验证我对数字证书的理解......让我解释一下。

据我通俗地理解,如果我有一个服务器的公共签名数字证书,那么该服务器证书将具有由 CA 创建的数字签名。例如,当我通过 https 浏览该服务器时,我的计算机将通过检查信任链来验证证书。因此,它获取数字证书,对其进行解密(使用 CA 的公钥)并显示哈希值。将此值与已签名数据的哈希值进行比较,如果它们匹配,则证书是由受信任的源签名的。

所以现在我想尝试和模拟的是手动验证我使用 openssl 在计算机上创建的数字签名。因此我做了以下事情:

## Create a key pair
$ openssl genrsa -aes128 -passout pass:Test123 -out private.pem 4096
$ openssl rsa -in private.pem -passin pass:Test123 -pubout -out public.pem

## Create a file as something to sign
$ touch filex
$ echo "some data" > filex

## Sign the file
$ openssl dgst -sha256 -sign private.pem -out data.txt.signature filex 

## Verify the signature
$ openssl dgst -sha256 -verify public.pem -signature data.txt.signature filex 
Verified OK

所以这证实了我想要的(尽管这里没有 CA)。我想要做的是查看它在解密数字签名时计算出的实际哈希值,这样我就可以在我的“filex”上运行 sha256sum 并比较两者。但我似乎找不到办法做到这一点。谁能帮助我找到实现这一目标的方法?

更新:由于有人发布了之前类似问题的链接,我尝试了该方法,但无法使其工作。因此,我将复制我在下面完成的步骤:

首先,我从我的浏览器中获取了 stackexchange.pem 和 CA 的 E1.pem 文件并下载了它。

$ openssl asn1parse -i -in stackexchange.pem 
    0:d=0  hl=4 l= 947 cons: SEQUENCE          
    4:d=1  hl=4 l= 824 cons:  SEQUENCE          
    8:d=2  hl=2 l=   3 cons:   cont [ 0 ]        
   10:d=3  hl=2 l=   1 prim:    INTEGER           :02
   13:d=2  hl=2 l=  18 prim:   INTEGER           :035FE125AEA1239BD263714150F2D8EE3C0F
   33:d=2  hl=2 l=  10 cons:   SEQUENCE          
   35:d=3  hl=2 l=   8 prim:    OBJECT            :ecdsa-with-SHA384
   45:d=2  hl=2 l=  50 cons:   SEQUENCE          
   47:d=3  hl=2 l=  11 cons:    SET               
   49:d=4  hl=2 l=   9 cons:     SEQUENCE          
   51:d=5  hl=2 l=   3 prim:      OBJECT            :countryName
   56:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :US
   60:d=3  hl=2 l=  22 cons:    SET               
   62:d=4  hl=2 l=  20 cons:     SEQUENCE          
   64:d=5  hl=2 l=   3 prim:      OBJECT            :organizationName
   69:d=5  hl=2 l=  13 prim:      PRINTABLESTRING   :Let's Encrypt
   84:d=3  hl=2 l=  11 cons:    SET               
   86:d=4  hl=2 l=   9 cons:     SEQUENCE          
   88:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
   93:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :E1
   97:d=2  hl=2 l=  30 cons:   SEQUENCE          
   99:d=3  hl=2 l=  13 prim:    UTCTIME           :231117014719Z
  114:d=3  hl=2 l=  13 prim:    UTCTIME           :240215014718Z
  129:d=2  hl=2 l=  28 cons:   SEQUENCE          
  131:d=3  hl=2 l=  26 cons:    SET               
  133:d=4  hl=2 l=  24 cons:     SEQUENCE          
  135:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
  140:d=5  hl=2 l=  17 prim:      PRINTABLESTRING   :stackexchange.com
  159:d=2  hl=2 l=  89 cons:   SEQUENCE          
  161:d=3  hl=2 l=  19 cons:    SEQUENCE          
  163:d=4  hl=2 l=   7 prim:     OBJECT            :id-ecPublicKey
  172:d=4  hl=2 l=   8 prim:     OBJECT            :prime256v1
  182:d=3  hl=2 l=  66 prim:    BIT STRING        
  250:d=2  hl=4 l= 578 cons:   cont [ 3 ]        
  254:d=3  hl=4 l= 574 cons:    SEQUENCE          
  258:d=4  hl=2 l=  14 cons:     SEQUENCE          
  260:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Key Usage
  265:d=5  hl=2 l=   1 prim:      BOOLEAN           :255
  268:d=5  hl=2 l=   4 prim:      OCTET STRING      [HEX DUMP]:03020780
  274:d=4  hl=2 l=  29 cons:     SEQUENCE          
  276:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Extended Key Usage
  281:d=5  hl=2 l=  22 prim:      OCTET STRING      [HEX DUMP]:301406082B0601050507030106082B06010505070302
  305:d=4  hl=2 l=  12 cons:     SEQUENCE          
  307:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Basic Constraints
  312:d=5  hl=2 l=   1 prim:      BOOLEAN           :255
  315:d=5  hl=2 l=   2 prim:      OCTET STRING      [HEX DUMP]:3000
  319:d=4  hl=2 l=  29 cons:     SEQUENCE          
  321:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Subject Key Identifier
  326:d=5  hl=2 l=  22 prim:      OCTET STRING      [HEX DUMP]:0414ABB9D50E8357BF0921BC299E1B83B6ED2A1BB326
  350:d=4  hl=2 l=  31 cons:     SEQUENCE          
  352:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Authority Key Identifier
  357:d=5  hl=2 l=  24 prim:      OCTET STRING      [HEX DUMP]:301680145AF3ED2BFC36C23779B95230EA546FCF55CB2EAC
  383:d=4  hl=2 l=  85 cons:     SEQUENCE          
  385:d=5  hl=2 l=   8 prim:      OBJECT            :Authority Information Access
  395:d=5  hl=2 l=  73 prim:      OCTET STRING      [HEX DUMP]:3047302106082B060105050730018615687474703A2F2F65312E6F2E6C656E63722E6F7267302206082B060105050730028616687474703A2F2F65312E692E6C656E63722E6F72672F
  470:d=4  hl=2 l=  75 cons:     SEQUENCE          
  472:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Subject Alternative Name
  477:d=5  hl=2 l=  68 prim:      OCTET STRING      [HEX DUMP]:304282182A2E6D6574612E737461636B65786368616E67652E636F6D82132A2E737461636B65786368616E67652E636F6D8211737461636B65786368616E67652E636F6D
  547:d=4  hl=2 l=  19 cons:     SEQUENCE          
  549:d=5  hl=2 l=   3 prim:      OBJECT            :X509v3 Certificate Policies
  554:d=5  hl=2 l=  12 prim:      OCTET STRING      [HEX DUMP]:300A3008060667810C010201
  568:d=4  hl=4 l= 260 cons:     SEQUENCE          
  572:d=5  hl=2 l=  10 prim:      OBJECT            :CT Precertificate SCTs
  584:d=5  hl=3 l= 245 prim:      OCTET STRING      [HEX DUMP]:0481F200F000770048B0E36BDAA647340FE56A02FA9D30EB1C5201CB56DD2C81D9BBBFAB39D884730000018BDB2CF9BB0000040300483046022100D3057AB69D47FA324E26A59D5210029843F17CA8034FD70045A2F6514098434B022100A693797A5A0EE660AC1C4D904079FC367F921826980340F6ED9C5D580C63CFC7007500EECDD064D5DB1ACEC55CB79DB4CD13A23287467CBCECDEC351485946711FB59B0000018BDB2CF9D1000004030046304402206044A6FAE9C47837ABA50300BFC5C2EBBD33705697EB5C7DB40BDAAC4638E16D02205EB94A42B09FFDE5277C7A2B02BCA288EA859E114B71B4C41D022CC3FFB6D427
  832:d=1  hl=2 l=  10 cons:  SEQUENCE          
  834:d=2  hl=2 l=   8 prim:   OBJECT            :ecdsa-with-SHA384
  844:d=1  hl=2 l= 105 prim:  BIT STRING        

我的标记是 4 和 844(844 之后 = sig)

抓取要签名的数据,并以二进制形式留下

$ openssl asn1parse -in stackexchange.pem -strparse 4 -out stackexchange.tbs

获取数字签名

$ openssl asn1parse -in stackexchange.pem -strparse 844 -out stackexchange.sig

从 CA 的 pem 文件中获取公钥

$openssl x509 -in E1.pem -noout -pubkey > e1.pub

检查输出

   $ openssl pkey -in e1.pub -pubin -text
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEJFwtoir9HEumXZdzJzGssqBpYu9l6Kaw
8KxLn/8cC3AP05gvTfwPAJs38HQFVzKXLgXvKkMlo/tuNCcT9k9+adMCmV7rJEeS
wSSb5rEhj8EkgfxozB9pulj1GSL3dMYW
-----END PUBLIC KEY-----
Public-Key: (384 bit)
pub:
    04:24:5c:2d:a2:2a:fd:1c:4b:a6:5d:97:73:27:31:
    ac:b2:a0:69:62:ef:65:e8:a6:b0:f0:ac:4b:9f:ff:
    1c:0b:70:0f:d3:98:2f:4d:fc:0f:00:9b:37:f0:74:
    05:57:32:97:2e:05:ef:2a:43:25:a3:fb:6e:34:27:
    13:f6:4f:7e:69:d3:02:99:5e:eb:24:47:92:c1:24:
    9b:e6:b1:21:8f:c1:24:81:fc:68:cc:1f:69:ba:58:
    f5:19:22:f7:74:c6:16
ASN1 OID: secp384r1
NIST CURVE: P-384

将要签名的字段哈希为二进制文件

$ openssl sha384 <stackexchange.tbs -binary >hash

现在执行手动验证

$ openssl pkeyutl -verify -in hash -sigfile stackexchange.sig -inkey e1.pub -pubin -pkeyopt digest:sha384
Signature Verified Successfully

啊糟糕,当我尝试编辑这篇文章并更新有关戴夫链接的方法不起作用时,我意识到我在实现它时犯了一个错误。因此,在编辑这篇文章时,我实际上已经给出了我想要的确切答案,而不是此更新的问题,因为我现在看到它验证成功。

我仍然想了解为什么@u1686_grawity 认为解密不参与验证,因为我愿意接受建议。然而,我的更新显示我手动对证书的所有待签名字段进行哈希处理,并将其哈希到名为“hash”的文件中,然后获取 E1.pem 的公共证书(原始证书的 CA) pem 文件)使用它作为解密密钥作为输入,并针对 .sig 文件运行它。由于我的哈希结果和解密的哈希值匹配,这意味着我从原始 pem 文件中提取的签名绝对经过 CA 验证并且是真实的。所以我很困惑为什么 u1686_grawity 和互联网上的许多其他人相信没有解密发生......

相关内容