【问题标题】:How to verify ECDSA signature with Crypto++ without the verify function?如何在没有验证功能的情况下使用 Crypto++ 验证 ECDSA 签名?
【发布时间】:2014-01-12 19:58:04
【问题描述】:

我使用 Crypto++ 使用 ECDSA 制作了 Signer/Checker 机制。

问题是当我想检查签名时,它不适用于验证功能。

您能否建议我一种更手动的方式来验证签名?

【问题讨论】:

  • 请发布一些您正在使用的代码。尽量减少测试用例。

标签: digital-signature crypto++ ecdsa


【解决方案1】:

如何在没有验证功能的情况下使用 Crypto++ 验证 ECDSA 签名?

我不确定如果没有验证功能,您将如何验证代码。我可能不明白这个问题。

以防万一,以下是 Crypto++ 实现其验证码的方式。

首先,ECDSA 是一个DL_Algorithm_ECDSA(来自eccrypto.h):

//! ECDSA algorithm
template <class EC>
class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
{
public:
    static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
};
...

template <class EC, class H>
struct ECDSA :
    public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>,
               DL_SignatureMessageEncodingMethod_DSA, H>
{
};

接下来,这里是来自DL_Algorithm_GDSA in gfcrypt.h 的验证函数:

bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey,
                const Integer &e, const Integer &r, const Integer &s) const
{
    const Integer &q = params.GetSubgroupOrder();
    if (r>=q || r<1 || s>=q || s<1)
        return false;

    Integer w = s.InverseMod(q);
    Integer u1 = (e * w) % q;
    Integer u2 = (r * w) % q;

    return r == params.ConvertElementToInteger(
                    publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
}

下面的代码使用VerifyMessage,它在cryptolib.h中声明的PK_Verifier的一部分:

virtual bool VerifyMessage(const byte *message, size_t messageLen, 
                 const byte *signature, size_t signatureLength) const;

PK_VerifierECDSANRRSASS 等对象用来公开一致接口的“主”基类。

ECDSANRRSASS 等对象通过 DL_SS 连接到 PK_Verifier

template <class EC, class H>
struct ECDSA :
    public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
{
};

最后,这是DL_SSPK_Verifier 的关系(来自pubkey.h):

//! Discrete Log Based Signature Scheme
template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
class DL_SS : public KEYS
{
    typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
    ...

    //! implements PK_Signer interface
    typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
    //! implements PK_Verifier interface
    typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
};

问题是当我想检查签名时,它不适用于验证功能。

Crypto++ wiki 上有很多可用的代码。对于 ECDSA,请参阅 Elliptic Curve Digital Signature Algorithm。下面是一个签名验证样本,取自 wiki。

签名

AutoSeededRandomPool prng;

ECDSA<ECP, SHA1>::PrivateKey privateKey;
privateKey.Load(...);
privateKey.Validate(prng, 3);

ECDSA<ECP, SHA1>::Signer signer(privateKey);

string message = "Do or do not. There is no try.";

// Determine maximum size, allocate a string with the maximum size
size_t siglen = signer.MaxSignatureLength();
string signature(siglen, 0x00);

// Sign, and trim signature to actual size
siglen = signer.SignMessage( prng, message.data(), message.size(), signature.data() );
signature.resize(siglen);

验证

AutoSeededRandomPool prng;

ECDSA<ECP, SHA1>::PublicKey publicKey;
publicKey.Load(...);
publicKey.Validate(prng, 3);

ECDSA<ECP, SHA1>::Verifier verifier(publicKey);

bool result = verifier.VerifyMessage( message.data(), message.size(), signature.data(), signature.size() );
if(result)
  cout << "Verified signature on message" << endl;
else
  cerr << "Failed to verify signature on message" << endl;

【讨论】:

  • 问题是我想用一个exe签署pe文件并保存密钥,而在另一个exe中我想加载公钥并检查签名
  • Wei 在 Crypto++ 的 test.cpp 中做了类似的事情。请参阅选项mac_dll 的代码。简而言之,mac_dll 打开可执行文件,使用HMAC 对代码进行校验和,然后将预期的指纹嵌入回可执行文件中以检测篡改。在运行时,可执行文件验证校验和代码上的签名。 mac_dll 存在是因为 FIPS 140-2 要求。另见Dynamic TEXT Section Image Verification
  • @jww 请查看此问题stackoverflow.com/questions/30950856/… 我正在尝试使用 ECDSA 进行签名和验证,但使用随机生成的密钥,它甚至没有签名
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多