如何在给定参数和键值的情况下创建 M2Crypto DSA 对象?

发布于 2024-09-04 23:51:25 字数 171 浏览 9 评论 0原文

我想使用 M2Crypto 创建一个 DSA_pub 对象来验证 DSA 签名。我知道 q、p、g 和公钥,但我知道实例化 DSA 对象的唯一方法是使用:

dsa = DSA.set_params(q,p,g)
dsa.gen_key()

如何分配已知的公钥?

Using M2Crypto I'd like to create a DSA_pub object for verifying a DSA signature. I know q, p, g, and the public key, but the only way I know to instantiate a DSA object is using:

dsa = DSA.set_params(q,p,g)
dsa.gen_key()

How do I assign the known public key?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

各空 2024-09-11 23:51:25

我刚刚遇到了这个挑战,我有 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)

I just ran across exactly this challenge, where I have the P, Q, G and Y parameters (in my case from an XML document), but M2Crypto does not have a way for me to create a valid public key from them.

I resorted to using pyasn1 to produce a PEM public key string, then loading that PEM public key using the M2Crypto.DSA.load_pub_key_bio factory function.

My rough code follows, in case it's useful to somebody in the future.

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)
混吃等死 2024-09-11 23:51:25

我最终创建了一个补丁,为 M2Crypto 添加了 pub_key_from_params 工厂方法,并且除了功能之外还包括回归测试。在本文发表时,功能请求的状态仍然是“新”:https:// /bugzilla.osafoundation.org/show_bug.cgi?id=12981 。过去几个月它对我很有用。如果开发人员发现它有用,也许它会被包含在内。

I ended up creating a patch that adds a pub_key_from_params factory method for M2Crypto and includes regression tests in addition to the functionality. The state of the feature request is still "NEW" at the time of this post: https://bugzilla.osafoundation.org/show_bug.cgi?id=12981 . It's worked for me for the past few months. If the developers find it useful, perhaps it will be included.

对你而言 2024-09-11 23:51:25

除了 get_params 之外,模块 DSA 中还有许多工厂函数,我认为您需要 load_pub_key(如果您在 PEM 文件中有公钥和参数)或 load_pub(如果您在 BIO 对象中有它们)。另请参阅 BIO 模块了解各种 BIO 对象。

There are many factory functions in module DSA beyond get_params, and I think you want load_pub_key (if you have public key and params in a PEM file) or load_pub (if you have them in a BIO object). See also the BIO module for various kinds of BIO objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文