如何根据参数和密钥值创建M2Crypto DSA对象?
我想用M2Crypto库创建一个DSA_pub对象来验证DSA签名。我知道参数q、p、g和公钥,但我知道的唯一方法是通过以下代码来实例化一个DSA对象:
dsa = DSA.set_params(q,p,g)
dsa.gen_key()
那么,我该如何给这个已知的公钥赋值呢?
3 个回答
0
在DSA
模块中,有很多工厂函数,不仅仅是get_params
。我觉得你可能需要的是load_pub_key(如果你有一个包含公钥和参数的PEM文件)或者load_pub
(如果你有这些内容在一个BIO对象中)。另外,你也可以查看BIO模块,里面有各种类型的BIO对象。
1
我最终创建了一个补丁,添加了一个叫做 pub_key_from_params 的工厂方法给 M2Crypto,并且还包括了回归测试,确保这个功能正常工作。发帖时,这个功能请求的状态仍然是“新建”。你可以在这里查看:https://bugzilla.osafoundation.org/show_bug.cgi?id=12981。在过去的几个月里,这个方法对我来说一直有效。如果开发者觉得这个方法有用,或许它会被加入到正式版本中。
2
我刚遇到一个类似的问题,我有一些参数P、Q、G和Y(在我的情况下是从一个XML文档中得到的),但是M2Crypto这个库没有办法让我用这些参数创建一个有效的公钥。
于是我决定使用pyasn1来生成一个PEM格式的公钥字符串,然后再用M2Crypto.DSA.load_pub_key_bio这个工厂函数来加载这个PEM公钥。
以下是我写的粗略代码,可能对将来某些人有帮助。
import sys
import M2Crypto
if sys.version_info[0] >= 3:
bin = "{0:#0b}".format
from functools import reduce
def _a2bits(chars):
"""Convert a string to its bits representation as a tuple of 0's and 1's"""
return tuple(c == '1' and 1 or 0 for c in (bin(reduce(lambda x, y : (x<<8)+y, (ord(c) for c in chars), 1))[3:]))
def _make_dsa_pubkey_pem(p, q, g, y):
from pyasn1.type import univ, namedtype
from pyasn1.codec.der import encoder
import base64
class DSSParameters(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType('p', univ.Integer()),
namedtype.NamedType('q', univ.Integer()),
namedtype.NamedType('g', univ.Integer())
)
class AlgorithmIdentifier(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType('algorithm', univ.ObjectIdentifier()),
namedtype.OptionalNamedType('parameters', DSSParameters())
)
class SubjectPublicKeyInfo(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType('algorithm', AlgorithmIdentifier()),
namedtype.NamedType('subjectPublicKey', univ.BitString()),
)
class DSAPublicKey(univ.Integer):
pass
dss_parameters = DSSParameters()
dss_parameters.setComponentByName('p', p)
dss_parameters.setComponentByName('q', q)
dss_parameters.setComponentByName('g', g)
algorithm_identifier = AlgorithmIdentifier()
algorithm_identifier.setComponentByName('algorithm', univ.ObjectIdentifier((1, 2, 840, 10040, 4, 1)))
algorithm_identifier.setComponentByName('parameters', dss_parameters)
subject_public_key_info = SubjectPublicKeyInfo()
subject_public_key_info.setComponentByName('algorithm', algorithm_identifier)
subject_public_key_info.setComponentByName('subjectPublicKey', _a2bits(encoder.encode(DSAPublicKey(y))))
der = encoder.encode(subject_public_key_info)
return '-----BEGIN PUBLIC KEY-----\n' + base64.encodestring(der) + '-----END PUBLIC KEY-----\n'
p = 8652574980431835801046702501319893323628737876463029580298337449414347224525946403948627650414713523236662848134622261400464992784181209952478362597409469
q = 1102869237300951505579173947124947290564874845679
g = 4112516799587510153843416910187202701228216851472313407150913894984801048587575223178182928872781591943506026197710239402382269043796703824161282824797865
y = 2998329614411012012383616762831086330705701157164243056626309777500058049666595469116052965199021788182564677073758748878456479902088304265763443201269078
pem = _make_dsa_pubkey_pem(p, q, g, y)
bio = M2Crypto.BIO.MemoryBuffer(pem)
dsapub = M2Crypto.DSA.load_pub_key_bio(bio)