微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

引发 ValueError("无效的 DER 输入:数据不足") ValueError:无效的 DER 输入:数据不足如何解决这个错误

如何解决引发 ValueError("无效的 DER 输入:数据不足") ValueError:无效的 DER 输入:数据不足如何解决这个错误

我正在尝试在我的区块链项目中使用 ED25519 签署和验证区块链交易,但我得到了一个

ValueError "无效的 DER 输入:数据不足

当我添加 encode_dss_signature 和 decode_dss_signature 时。

我首先将数据转换为 json 格式,然后将其编码为 (utf-8) 格式。然后当我尝试使用 decode_dss_signature 解码签名时。它给出了上述值错误

import json
import uuid 
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.utils import(
    encode_dss_signature,decode_dss_signature
)

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import serialization

class Wallet:
    """
    An individual wallet for a miner.
    Keeps track of the miners's balance.
    Allows a miner to authorize transactions.
    """
    def __init__(self):
        self.address = str(uuid.uuid4())[0:8] 
        self.private_key = Ed25519PrivateKey.generate()
        self.public_key = self.private_key.public_key()
        self.serialize_public_key()

    def sign(self,data):
        """
        Generate a signature based on the data using the local private key.
        """
        return decode_dss_signature(self.private_key.sign(
            json.dumps(data).encode('utf-8')
        ))


    def serialize_public_key(self):
        """
        Reset the public key to its serialized version.
        """
        self.public_key = self.public_key.public_bytes(
            encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo
        ).decode('utf-8')

        print(f'\n-- self.public_key: {self.public_key}')


    @staticmethod
    def verify(public_key,signature,data):
        """
        Verify signature based on original public_key and data.
        """

        deserialized_public_key = serialization.load_pem_public_key(
            public_key.encode('utf-8')
        )

        print(f'\n--signature: {signature}\n')
        (r,s) = signature

        try:
            deserialized_public_key.verify(
                encode_dss_signature(r,s),json.dumps(data).encode('utf-8')
            )

            return True

        except InvalidSignature:
            return False


def main():
    wallet = Wallet()
    print(f'wallet.__dict__: {wallet.__dict__}')

    data = { 'foo':'bar' }

    signature = wallet.sign(data)
    print(f'signature: {signature}')

    sign_verification = Wallet.verify(wallet.public_key,data)
    print(f'sign_verification: {sign_verification}')

   sign_verify_Failed = Wallet.verify(Wallet().public_key,data)
   print(f'sign_verify_Failed: {sign_verify_Failed}')

if __name__ == '__main__':
    main()

解决方法

我在测试中发现,根据 private_key 生成的 Ed25519PrivateKey,我最终得到了不同的错误。

通过简单地按照发布的程序运行 10,000 次,我得到了以下所有 ValueError 类型:

值错误信息 出现次数 出现百分比
无效的DER输入:数据不足 7193 71.93%
无效的DER输入:意外的标签 2389 23.89%
无效的DER输入:意外的高标签号 334 3.34%
无效的DER输入:DER中不允许不定长形式 39 0.39%
无效的 DER 输入:长度未最低编码 31 0.31%
无效的DER输入:尾随数据 14 0.14%

您可以自己尝试:

from collections import Counter


def main():
    c = Counter()
    for i in range(10_000):
        try:
            wallet = Wallet()
            data = { 'foo':'bar' }
            wallet.sign(data)
        except ValueError as e:
            c.update([str(e)])
    print(c)

虽然,cryptography.hazmat.primitives.asymmetric.utils.decode_dss_signature(signature) 理论上

接收由 DSA/ECDSA 签名者生成的签名并返回一个元组 (r,s)。这些签名是 ASN.1 编码的 Dss-Sig-Value 序列(如 RFC 3279 中所定义)

虽然理论上

Ed25519 是一种使用 EdDSA 和 Curve25519 的椭圆曲线签名算法。如果您没有遗留互操作性问题,那么您应该强烈考虑使用此签名算法。

就本程序而言,sign产生的值不符合decode_dss_signature的预期输入

在将公钥和私钥传递给 decode_dss_signature 之前,我尝试了所有可能的公钥和私钥编码。虽然更改编码和格式确实改变了收到 ValueError 的速率和类型,但我仍然始终收到相同类型的错误。

可能有一种方法可以确保生成的私钥符合 decode_dss_signature 的预期标准,但我无法找到有关此特定功能的文档或用例的太多信息。

由于 encode_dss_signaturedecode_dss_signatureED25519 的行为不符合预期,我最终直接返回了 signverify 的结果。

import json
import uuid

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey


class Wallet:
    """
    An individual wallet for a miner.
    Keeps track of the miners's balance.
    Allows a miner to authorize transactions.
    """

    def __init__(self):
        self.address = str(uuid.uuid4())[0:8]
        self.private_key = Ed25519PrivateKey.generate()
        self.public_key = self.private_key.public_key()
        self.serialize_public_key()

    def sign(self,data):
        """
        Generate a signature based on the data using the local private key.
        """
        return self.private_key.sign(
            json.dumps(data).encode('utf-8')
        )

    def serialize_public_key(self):
        """
        Reset the public key to its serialized version.
        """
        self.public_key = self.public_key.public_bytes(
            encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo
        ).decode('utf-8')

    @staticmethod
    def verify(public_key,signature,data):
        """
        Verify signature based on original public_key and data.
        """

        deserialized_public_key = serialization.load_pem_public_key(
            public_key.encode('utf-8')
        )

        try:
            deserialized_public_key.verify(
                signature,json.dumps(data).encode('utf-8')
            )
            return True
        except InvalidSignature:
            return False


def main():
    wallet = Wallet()

    data = {'foo': 'bar'}

    signature = wallet.sign(data)
    print(f'signature: {signature}')

    sign_verification = Wallet.verify(wallet.public_key,data)
    print(f'sign_verification: {sign_verification}')

    sign_verify_failed = Wallet.verify(Wallet().public_key,data)
    print(f'sign_verify_failed: {sign_verify_failed}')


if __name__ == '__main__':
    main()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?