【问题标题】:ECDSA Not Signing/Verifying CorrectlyECDSA 未正确签名/验证
【发布时间】:2015-01-23 16:54:17
【问题描述】:

我目前在使用 Crypto++ 签名/验证字符串时遇到问题。几个月来,我已经尝试了这个网站上列出的方法,但没有成功。我之前尝试过发布在这里的 C 风格解决方案:http://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm,但目前正在使用过滤器进行实现。

我在下面的尝试是对此处发布的解决方案的修改:Get ECDSA signature with Crypto++

以下代码输出错误: ERROR: VerifierFilter: digital signature not valid

ECDSA<ECP, SHA256>::PrivateKey privateKey;
ECDSA<ECP, SHA256>::PublicKey publicKey;

AutoSeededRandomPool prng, rrng;

privateKey.Initialize(prng, CryptoPP::ASN1::secp256k1());

privateKey.MakePublicKey(publicKey);

string signature;

signature.erase();

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

StringSource(message, true,
     new SignerFilter(rrng,
     ECDSA<ECP, SHA256>::Signer(privateKey),
     new StringSink(signature)));

 try
 {
     StringSource(signature + message, true,
         new SignatureVerificationFilter(
         ECDSA<ECP, SHA256>::Verifier(publicKey), NULL,
         SignatureVerificationFilter::THROW_EXCEPTION
         ) // SignatureVerificationFilter   
         ); // StringSource 
 }
 catch (CryptoPP::Exception& e)
 {
     std::cerr << "\n\nERROR: " << e.what() << std::endl;
 }

感谢您的帮助。

【问题讨论】:

    标签: c++ cryptography signing crypto++ ecdsa


    【解决方案1】:

    在浏览 Wiki 更长的时间后,我想我可能偶然发现了解决方案。

    http://www.cryptopp.com/wiki/SignatureVerificationFilter#Signature_Generation_and_Verification

    在上面的示例中,过滤器接收到的串联 消息+签名。当 SIGNATURE_AT_BEGIN 未在 构造函数,SIGNATURE_AT_END 是隐含的,签名是 验证必须在消息后呈现。如果签名是 首先插入,SIGNATURE_AT_BEGIN 必须指定为 附加标志值如下所示。

    因为使用了THROW_EXCEPTION,所以signaturemessage 必须交换,或者必须添加SIGNATURE_AT_BEGIN。在这种情况下,下面的代码不会抛出异常。

    StringSource ss(signature + message, true,
        new SignatureVerificationFilter(
        verifier, NULL,
        THROW_EXCEPTION | SIGNATURE_AT_BEGIN
            ) // SignatureVerificationFilter   
            ); // StringSource  
    

    【讨论】:

      【解决方案2】:
      StringSource(signature + message, true,
          new SignatureVerificationFilter(
              ECDSA<ECP, SHA256>::Verifier(publicKey), NULL,
              SignatureVerificationFilter::THROW_EXCEPTION
          ) // SignatureVerificationFilter   
      ); //
      

      上面看起来很可疑。它看起来很可疑有两个原因。首先,它使用匿名声明,而且我知道某些版本的 GCC 会产生不好的结果。 GCC 生成的代码使得析构函数运行得太快。所以命名你的声明。

      其次,SignatureVerificationFilter 接受引用,而不是临时引用。因此,您应该提供对verifier 的引用,或者使用Ref() 成员函数(如果可用)。

      首先,尝试一下:

      ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
      
      StringSource ss(signature + message, true,
          new SignatureVerificationFilter(
              verifier, NULL,
              SignatureVerificationFilter::THROW_EXCEPTION
          ) // SignatureVerificationFilter   
      ); // StringSource 
      

      其次,试试:

      StringSource ss(signature + message, true,
          new SignatureVerificationFilter(
              ECDSA<ECP, SHA256>::Verifier(publicKey).Ref(), NULL,
              SignatureVerificationFilter::THROW_EXCEPTION
          ) // SignatureVerificationFilter   
      ); // StringSource
      

      但我不确定ECDSA&lt;ECP, SHA256&gt;::Verifier(publicKey).Ref() 是否有效。

      【讨论】:

      • @stacker - 我知道你从哪里得到代码(遗憾的是,我可能是写它的人)。我会在下次播出时修复这些 wiki 页面。
      • @ jww - 这两个选项都不适合我。我也将您在第一个解决方案中的修改应用于我的签名,但没有运气。此外, Ref() 显然不是成员。感谢您的帮助。
      • @stacker - 在签名者代码中应用相同的更改,以防创建错误签名(这将解释验证失败)。
      • 好的,我的代码保持不变,只是替换了上面的两个摘录。然后我修改了签名部分,三个尝试都失败了。验证者是解决签名过程故障的唯一方法吗?谢谢。
      • 我刚刚发布了我的问题的答案。你能确认这是正确的吗?谢谢。
      猜你喜欢
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多