python rfc3161验证失败,但openssl验证可以



我正在尝试对我的内容进行时间戳,以便知道它何时更改。首先我使用了一个shell脚本,但我想在我的python程序中实现它。shell脚本目前运行良好,但我无法让python版本为我工作。这是正在运行的外壳版本

in_file='test_content'
out_file="${in_file}.tsr"
ts_server='http://time.certum.pl/'
openssl ts -query -data "$in_file" -sha1 -cert | curl -o "$out_file" -sSH 'Content-Type: application/timestamp-query' --data-binary @- "$ts_server"
openssl ts -verify -data "$in_file" -in "$out_file" -CAfile "/usr/lib/ssl/certs/Certum_Trusted_Network_CA.pem"
openssl ts -reply -in "$out_file" -text

我试着用rfc3161包来模仿这个,但验证并没有像预期的那样进行。这是python代码

import rfc3161
cert = file('/usr/lib/ssl/certs/Certum_Trusted_Network_CA.pem').read()
rt = rfc3161.RemoteTimestamper('http://time.certum.pl/', certificate=cert)
data_to_sign = file('test_content').read()
print rt.timestamp(data=data_to_sign)
>>> (False, 'Bad signature')

我不知道出了什么问题,因为两个脚本都应该做同样的事情。有人能告诉我python版本出了什么问题吗?

以下代码使用工作

  • Python 3
  • 模块rfc3161ng(无论如何也可用于python 2.7)
  • FreeTSA

因为

  • 不再维护Python 2和模块rfc3161
  • 我不确定certum.pl端点url以及在哪里可以获得正确的CA证书

您应该选择哈希算法(默认值为sha1,不推荐使用)。

import rfc3161ng
import os
from struct import unpack
with open('freetsa.pem', 'rb') as cert_fh:
    cert = cert_fh.read()
rt = rfc3161ng.RemoteTimestamper('https://freetsa.org/tsr', certificate=cert, hashname='sha256')
with open('test_content', 'rb') as content_fh:
    data_to_sign = content_fh.read()
nonce = unpack('<q', os.urandom(8))[0]
print(rt.timestamp(data=data_to_sign))

安全警告

Nonce是可选的,但建议使用,如RFC3161 第2.4.1段所述

nonce(如果包括在内)允许客户端验证当没有本地时钟可用时的响应。nonce是一个大客户端生成概率很高的随机数仅一次(例如64位整数)。

python-rfc3161的作者。如果返回了错误的签名,这意味着您为TSA申报的证书不是真正用于签名的证书。

melanholly提供的补丁对我来说似乎不正确,如果你不能验证其来源(例如使用PKI),你永远不应该使用与签名捆绑的证书来检查。这里的情况似乎并非如此。

问题出在我使用的库rfc3161中。作者似乎不包括TSA授权证书的检查,所以我不得不更改图书馆。

更改后的代码在check_timestamp函数中的api.py中。您必须用以下代码块更改证书加载的代码块:

编辑:应根据某个证书存储验证响应中的证书。如果你不能验证它,你应该提出一个异常

if certificate != "":
    try:
        certificate = X509.load_cert_der_string(encoder.encode(signed_data['certificates'][0][0]))
        # YOU SHOULD VALIDATE THE CERTIFICATE AGAINST SOME CERTIFICATE STORE !!!! 
        if not validate_certificate(certificate): #NOTE: I am not ready with this function.
            raise TypeError('The TSA returned certificate should be valid one')
    except:
        raise AttributeError("missing certificate")
else:
    try:
        certificate = X509.load_cert_string(certificate)
    except:
        certificate = X509.load_cert_der_string(certificate)

EDIT2:对于验证,您可以使用此处描述的代码:

现在验证工作如预期。

相关内容

  • 没有找到相关文章

最新更新