首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在python中验证签名文件

如何在python中验证签名文件
EN

Stack Overflow用户
提问于 2018-05-30 23:05:16
回答 1查看 10.5K关注 0票数 10

背景

我已经使用openssl SHA256和私钥签署了一个文件,如下所示:

with subprocess.Popen(
        # Pipe the signature to openssl to convert it from raw binary encoding to base64 encoding.
        # This will prevent any potential corruption due to line ending conversions, and also allows 
        # a human to read and copy the signature (e.g. for manual verification).
        'openssl dgst -sha256 -sign private.key sign_me.zip | openssl base64 > signature.sha256',
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        shell=True,
) as proc:
    out, _ = proc.communicate()

要求

  1. I需要使用signature.sha256 public_key.crt 和 modified.
  2. Compatible 来验证Python3.2-3.4中是否还没有modified.
  3. Compatible
  4. 需要同时在和Redhat上工作,并且不能保证OpenSSL会在路径上或已知位置。理想情况下,我希望使用核心Python模块,但如果第三方模块降低了复杂性,我会考虑使用它。

我尝试过的

我做了很多搜索,试图找出如何做到这一点,但我还没有能够找到一个令人满意的答案。下面是我尝试和/或研究过的东西的列表:

  • 我可以通过以下外壳命令手动验证签名。由于要求3,这不能作为一个永久的解决方案。

openssl dgst -sha256 -verify <(openssl x509 -in public_key.crt -pubkey -noout) -signature signature.sha256 sign_me.zip

  • I找到了this question,这几乎就是我想要做的。近两年来,它一直没有得到回复,甚至也没有评论过。它提到了ssl python library,它主要处理客户端/服务器证书,并且sockets.

  • This question似乎使用加密库来验证"SHA256withRSA和PKCS1填充“签名。不幸的是,它的目标是Python2.7,另外,我无法在Python2.7的crypto模块中找到verify()方法文档,因为party references.

  • I还发现了一个名为cryptography的第三方模块。关于堆栈溢出的共识似乎是,这是最新/最好的加密模块,但我找不到与我的requirements.

匹配的文档

也许我漏掉了一些明显的东西?我在安全性/加密/散列方面没有做过太多的工作,所以欢迎反馈。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-14 03:09:32

感谢Patrick Mevzek为我指明了正确的方向。我最终使用Cryptography模块找到了以下问题的解决方案。我最终更改了签名文件的方式,以便与稍后验证它的方式相匹配。

密钥生成:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

# Generate the public/private key pair.
private_key = rsa.generate_private_key(
    public_exponent = 65537,
    key_size = 4096,
    backend = default_backend(),
)

# Save the private key to a file.
with open('private.key', 'wb') as f:
    f.write(
        private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption(),
        )
    )

# Save the public key to a file.
with open('public.pem', 'wb') as f:
    f.write(
        private_key.public_key().public_bytes(
            encoding = serialization.Encoding.PEM,
            format = serialization.PublicFormat.SubjectPublicKeyInfo,
        )
    )

签名:

import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding

# Load the private key. 
with open('private.key', 'rb') as key_file: 
    private_key = serialization.load_pem_private_key(
        key_file.read(),
        password = None,
        backend = default_backend(),
    )

# Load the contents of the file to be signed.
with open('payload.dat', 'rb') as f:
    payload = f.read()

# Sign the payload file.
signature = base64.b64encode(
    private_key.sign(
        payload,
        padding.PSS(
            mgf = padding.MGF1(hashes.SHA256()),
            salt_length = padding.PSS.MAX_LENGTH,
        ),
        hashes.SHA256(),
    )
)
with open('signature.sig', 'wb') as f:
    f.write(signature)

验证:

import base64
import cryptography.exceptions
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import load_pem_public_key

# Load the public key.
with open('public.pem', 'rb') as f:
    public_key = load_pem_public_key(f.read(), default_backend())

# Load the payload contents and the signature.
with open('payload.dat', 'rb') as f:
    payload_contents = f.read()
with open('signature.sig', 'rb') as f:
    signature = base64.b64decode(f.read())

# Perform the verification.
try:
    public_key.verify(
        signature,
        payload_contents,
        padding.PSS(
            mgf = padding.MGF1(hashes.SHA256()),
            salt_length = padding.PSS.MAX_LENGTH,
        ),
        hashes.SHA256(),
    )
except cryptography.exceptions.InvalidSignature as e:
    print('ERROR: Payload and/or signature files failed verification!')
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50608010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档