我正在尝试将我的内容加上时间戳,以便知道它何时被更改。首先我使用了一个shell脚本,但我想在我的python程序中实现它。 shell脚本现在工作正常但我不能让python版本适合我。 这是正常工作 shell版本
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 package模仿这个,但验证没有按预期进行。这是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版本有什么问题的线索吗?
答案 0 :(得分:2)
以下代码使用
因为
您应该选择哈希算法(默认为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段所述随机数(如果包含)允许客户验证以下情况的及时性: 没有本地时钟可用时的响应。随机数很大 客户端生成它的可能性很高的随机数 仅一次(例如64位整数)。
答案 1 :(得分:0)
问题在于我使用的库rfc3161。似乎作者没有包含TSA权威证书的检查,因此我不得不对库进行更改。
更改的代码位于api.py
函数的check_timestamp
中。您必须使用以下代码更改证书加载的代码块:
修改强> 响应中的证书应针对某些证书存储进行验证。如果您无法验证它,则应该引发异常
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:进行验证,您可以使用here描述的代码:
现在验证工作正常。
答案 2 :(得分:0)
python-rfc3161的作者在这里。如果返回错误签名,则表示您为TSA声明的证书不是真正用于签名的证书。
melanholly提供的补丁对我来说似乎不对,你永远不应该使用捆绑了签名的证书来检查你是否无法验证其来源(例如使用PKI)。这似乎不是这种情况。