如何解决引发 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_signature
和 decode_dss_signature
与 ED25519
的行为不符合预期,我最终直接返回了 sign
和 verify
的结果。
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 举报,一经查实,本站将立刻删除。