[英]Signing huge file with pyOpenSSL
I need to create SSL signatures for large *.tar.gz
files (gigabytes of data) using Python 3 and pyopenssl
module. 我需要使用Python 3和pyopenssl
模块为大型*.tar.gz
文件(千兆字节的数据)创建SSL签名 。
Below is simplified excerpt of my code (that works). 下面是我的代码的简化摘录(有效)。 The problematic line is the following one: 问题行如下:
bytes_to_sign = sign_file.read() # PROBLEM if file is LARGE
Reading whole file at once is probably not best idea but I don't know how to do it in other way. 一次读取整个文件可能不是最好的主意,但我不知道如何以其他方式进行。
Here is the code: 这是代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import OpenSSL
import argparse
import getpass
import logging
DIGEST_METHOD = 'sha256'
SSL_CERT_FORMAT_TYPE = OpenSSL.crypto.FILETYPE_PEM
LOG_FORMAT = '[%(asctime)s][ %(levelname)s ] %(message)s'
def create_args_parser():
p = argparse.ArgumentParser(description='Simple SSL signature generator.')
p.add_argument('file', type=argparse.FileType('rb'),
metavar='signed_file_path',
help='path to the file that will be signed')
p.add_argument('--ssl-key', type=argparse.FileType(),
metavar='CERT_PATH', required=True,
help='path to SSL certificate private key in PEM format')
p.add_argument('-o', '--out', type=argparse.FileType('wb'),
metavar='SIGNATURE_PATH', required=True,
help='path where generated signature will be saved')
return p
def get_priv_key_obj(ssl_key_file):
"""Get password protecting SSL private key and create private key object."""
priv_key_str = ssl_key_file.read()
ssl_key_file.close() # https://stackoverflow.com/a/18863046/1321680
priv_key = None
while not priv_key:
ssl_passwd = getpass.getpass()
try:
priv_key = OpenSSL.crypto.load_privatekey(SSL_CERT_FORMAT_TYPE,
priv_key_str,
ssl_passwd.encode('ascii'))
except OpenSSL.crypto.Error:
logging.warning('Probably wrong password - try again')
return priv_key
def sign_file(priv_key, sign_file, out_file):
"""Sign given file with SSL private key and save signature in given file."""
bytes_to_sign = sign_file.read() # PROBLEM if file is LARGE
sign = OpenSSL.crypto.sign(priv_key, bytes_to_sign, DIGEST_METHOD)
sign_file.close()
out_file.write(sign)
out_file.close()
def main():
parser = create_args_parser()
args = parser.parse_args()
priv_key = get_priv_key_obj(args.ssl_key)
sign_file(priv_key, args.file, args.out)
if __name__ == '__main__':
try:
logging.basicConfig(format=LOG_FORMAT)
main()
except Exception as e:
logging.exception('Generating SSL certificate has failed. Check if '
'SSL cert password is correct. Details: {}'.format(e))
Script --help
: 脚本--help
:
usage: sign.py [-h] --ssl-key CERT_PATH -o SIGNATURE_PATH signed_file_path
Simple SSL signature generator.
positional arguments:
signed_file_path path to the file that will be signed
optional arguments:
-h, --help show this help message and exit
--ssl-key CERT_PATH path to SSL certificate private key saved in PEM
format
-o SIGNATURE_PATH, --out SIGNATURE_PATH
path where generated signature will be saved
Is there any way to not read()
the whole file at once? 有没有办法不一次read()
整个文件?
To verify the created signature run (or alternatively implement verification using pyOpenSSL
): 要验证运行的签名(或使用pyOpenSSL
验证 ):
openssl dgst -sha256 -verify cert_public_key_file.pub -signature cert_file.crt signed_file_path
If you need to create SSL certificate to test it, see this tutorial . 如果您需要创建SSL证书进行测试,请参见本教程 。
You have to implement your own chunked sign
Function. 您必须实现自己的chunked sign
功能。
But what about the Recipient, will it be able to verify? 但是收件人可以验证吗?
Read about: EVP_DigestSignInit 阅读有关: EVP_DigestSignInit
EVP_DigestSignUpdate() hashes cnt bytes of data at d into the signature context ctx. EVP_DigestSignUpdate()将d处的cnt字节数据散列到签名上下文ctx中。
This function can be called several times on the same ctx to include additional data. 可以在同一ctx上多次调用此函数以包含其他数据。
Adapt from def sign(pkey, data, digest): 改用def符号(pkey,数据,摘要):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.