Python 使用pyOpenSSL对大型文件进行签名

Python 使用pyOpenSSL对大型文件进行签名,python,python-3.x,ssl,ssl-certificate,pyopenssl,Python,Python 3.x,Ssl,Ssl Certificate,Pyopenssl,我需要使用和模块创建大文件(千兆字节的数据) 下面是我的代码(有效)的简化摘录。有问题的一行如下: 一次阅读整个文件,但我不知道如何用其他方式来做 代码如下: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import OpenSSL import argparse import getpass import logging DIGEST_METHOD = 'sha256' SSL_CERT_FORMAT_TYPE = OpenSSL.crypt

我需要使用和模块创建大文件(千兆字节的数据)

下面是我的代码(有效)的简化摘录。有问题的一行如下:

一次阅读整个文件,但我不知道如何用其他方式来做

代码如下:

#!/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))
脚本
--帮助

用法:sign.py[-h]--ssl密钥证书路径-o签名路径签名路径文件路径
简单的SSL签名生成器。
位置参数:
已签名\u文件\u路径将要签名的文件的路径
可选参数:
-h、 --帮助显示此帮助消息并退出
--ssl密钥证书路径保存在PEM中的ssl证书私钥的路径
格式
-o签名路径,-out签名路径
将保存生成的签名的路径
有没有办法一次不把整个文件都查出来


  • 要运行(或实现)已创建的签名,请执行以下操作:

  • 如果需要创建SSL证书来测试它,请参阅

  • 我知道有,但他们没有回答我的问题

您必须实现自己的
分块符号功能。
但是接收者呢,它能够验证吗

阅读:
EVP_DigestSignUpdate()将d处的cnt字节数据散列到签名上下文ctx中。
可以在同一个ctx上多次调用此函数以包含其他数据


改编自


还没有,但我希望我会有问题,因为:当大小被省略或负数时,文件的全部内容将被读取并返回;如果文件的大小是机器内存的两倍,那就是你的问题。我没有时间重新实现库的一部分。我希望这个问题能更容易解决。事实证明,它不够成熟和灵活,无法用于复杂的软件中-(引用自:pyOpenSSL是OpenSSL库(其子集)的一个相当薄的包装器。使用瘦包装器,我们的意思是许多对象方法只不过是调用OpenSSL库中的相应函数。
#!/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))
openssl dgst -sha256 -verify cert_public_key_file.pub -signature cert_file.crt signed_file_path