代码之家  ›  专栏  ›  技术社区  ›  Lery

使用ECDSA或DSA对预计算哈希进行签名

  •  3
  • Lery  · 技术社区  · 8 年前

    我正在与Crypto++签名者玩游戏,并直接从wiki中使用以下代码:

    ECDSA<ECP, SHA256>::PrivateKey privateKey;
    const Integer D(string("8964e19c5ae38669db3047f6b460863f5dc6c4510d3427e33545caf9527aafcf").c_str());
    privateKey.Initialize(CryptoPP::ASN1::secp256r1(), D);
    if (!privateKey.Validate(rng, 3)) {
        cerr << "ECDSA privateKey key validation failed after setting private parameter." << endl;
        return 1;
    }
    
    ECDSA<ECP,SHA256>::Signer signer(privateKey);
    StringSource ss1(message, true,
        new SignerFilter(rng, signer,
            new HexEncoder(new StringSink(signature), false)
        ) // SignerFilter
    ); // StringSource
    int slen = signature.length() / 2;
    // since it's IEEE P1363 format to display r and s:
    cout << signature.substr(0, slen) << "\n"
         << signature.substr(slen, slen) << endl;
    

    现在,我想知道如何重写那里的SHA256,以直接指定要传递给签名算法的摘要值。

    我已经深入研究了 wiki doxygen documentation ,但没有成功。起初我想也许 NullHash PK_MessageAccumulator 但它似乎并没有像我预期的那样起作用。

    那么,有没有从HashTransformation类继承的某种“identity”函数,我完全错过了?
    如果没有,您将如何构建这样的东西,允许指定要直接签名的摘要?

    1 回复  |  直到 8 年前
        1
  •  3
  •   jww avp    8 年前

    H(M)=M 可能有用。有可能满足这样一个习惯吗 HashTransformation ECDSA<ECP,H>::Signer ?

    对程序如下。它提供了一个 IdentityHash 将输入复制到输出的类。它需要一个模板参数来指定哈希大小。

    to_sign = MF(H(M)) .

    $ cat test.cxx
    #include "cryptlib.h"
    #include "secblock.h"
    #include "eccrypto.h"
    #include "osrng.h"
    #include "oids.h"
    #include "hex.h"
    
    #include <iostream>
    #include <string>
    
    using namespace CryptoPP;
    
    template <unsigned int HASH_SIZE = 32>
    class IdentityHash : public HashTransformation
    {
    public:
        CRYPTOPP_CONSTANT(DIGESTSIZE = HASH_SIZE)
        static const char * StaticAlgorithmName()
        {
            return "IdentityHash";
        }
    
        IdentityHash() : m_digest(HASH_SIZE), m_idx(0) {}
    
        virtual unsigned int DigestSize() const
        {
            return DIGESTSIZE;
        }
    
        virtual void Update(const byte *input, size_t length)
        {
            size_t s = STDMIN(STDMIN<size_t>(DIGESTSIZE, length),
                                             DIGESTSIZE - m_idx);    
            if (s)
                ::memcpy(&m_digest[m_idx], input, s);
            m_idx += s;
        }
    
        virtual void TruncatedFinal(byte *digest, size_t digestSize)
        {
            if (m_idx != DIGESTSIZE)
                throw Exception(Exception::OTHER_ERROR, "Input size must be " + IntToString(DIGESTSIZE));
    
            ThrowIfInvalidTruncatedSize(digestSize);
    
            if (digest)
                ::memcpy(digest, m_digest, digestSize);
    
            m_idx = 0;
        }
    
    private:
        SecByteBlock m_digest;
        size_t m_idx;
    };
    
    int main(int argc, char* argv[])
    {
        AutoSeededRandomPool prng;
    
        ECDSA<ECP, IdentityHash<32> >::PrivateKey privateKey;
        privateKey.Initialize(prng, ASN1::secp256r1());
    
        std::string message;
        message.resize(IdentityHash<32>::DIGESTSIZE);
        ::memset(&message[0], 0xAA, message.size());
    
        ECDSA<ECP, IdentityHash<32> >::Signer signer(privateKey);
        std::string signature;
    
        StringSource ss(message, true,
                            new SignerFilter(prng, signer,
                                new HexEncoder(new StringSink(signature))
                            ) // SignerFilter
                        ); // StringSource
    
        std::cout << "Signature: " << signature << std::endl;
    
        return 0;
    }
    

    我知道它编译并生成输出。我不知道输出是否正确:

    skylake:cryptopp$ g++ test.cxx ./libcryptopp.a -o test.exe
    skylake:cryptopp$ ./test.exe
    Signature: cafb8fca487c7d5023fbc76ccf96f107f72a07fecca77254e8845a2c8f2ed0ee8b50b
    8ee0702beb7572eaa30c8d250a7b082c79f2f02e58ccfb97d7091755e91
    

    你可以测试 识别灰烬 具有以下内容。班级 识别灰烬 与上一个示例没有更改。这个 main

    $ cat test.cxx
    #include "cryptlib.h"
    #include "secblock.h"
    
    #include <iostream>
    #include <string>
    
    using namespace CryptoPP;
    
    template <unsigned int HASH_SIZE = 32>
    class IdentityHash : public HashTransformation
    {
    public:
        CRYPTOPP_CONSTANT(DIGESTSIZE = HASH_SIZE)
        static const char * StaticAlgorithmName()
        {
            return "IdentityHash";
        }
    
        IdentityHash() : m_digest(HASH_SIZE), m_idx(0) {}
    
        virtual unsigned int DigestSize() const
        {
            return DIGESTSIZE;
        }
    
        virtual void Update(const byte *input, size_t length)
        {
            size_t s = STDMIN(STDMIN<size_t>(DIGESTSIZE, length),
                                             DIGESTSIZE - m_idx);    
            if (s)
                ::memcpy(&m_digest[m_idx], input, s);
            m_idx += s;
        }
    
        virtual void TruncatedFinal(byte *digest, size_t digestSize)
        {
            if (m_idx != DIGESTSIZE)
                throw Exception(Exception::OTHER_ERROR, "Input size must be " + IntToString(DIGESTSIZE));
    
            ThrowIfInvalidTruncatedSize(digestSize);
    
            if (digest)
                ::memcpy(digest, m_digest, digestSize);
    
            m_idx = 0;
        }
    
    private:
        SecByteBlock m_digest;
        size_t m_idx;
    };
    
    int main(int argc, char* argv[])
    {
        std::string message;
        message.resize(IdentityHash<32>::DIGESTSIZE);
        ::memset(&message[0], 'A', message.size());
    
        IdentityHash<32> hash;
        hash.Update((const byte*)message.data(), message.size());
    
        std::string digest(32, 0);
        hash.TruncatedFinal((byte*)digest.data(), digest.size());
    
        std::cout << "Message: " << message << std::endl;
        std::cout << " Digest: " << digest << std::endl;
    
        return 0;
    }
    

    skylake:cryptopp$ g++ test.cxx ./libcryptopp.a -o test.exe
    skylake:cryptopp$ ./test.exe
    Message: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     Digest: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA