【问题标题】:Import RSA public/private key from a string Crypto++从字符串 Crypto++ 导入 RSA 公钥/私钥
【发布时间】:2018-01-13 08:08:37
【问题描述】:

我想直接从字符串变量中导入 RSA 密钥,以将其与 Crypto++ 库一起使用。

代码如下所示: 这是我想做的一个例子,而不是一个工作代码。

std::string publickey_str =
    "-----BEGIN PUBLIC KEY-----"
    "gm6mZA1NTZQJVUk9AGDb6NRngzRlRAgXBTWAispwlqsuHFoCrv02xPm1uxkLyfUq"
    "LoA4/EQJ25okjmGkrjgak+XmQIPKmAg94gWAtvRIrLZNmCj/aPeuikmCPXkKtg2b"
    "pdB6xzHY0ftGu0l6Vb8zttg7Wfo1kJowjoqCRwo9ex/IKwPXxE3UsugshcZOGdqT"
    "6E3B/Vw+JoerL/LfeOU2OYcSFEXsWqjzkrGzEVuKzRnve5RlXyY0gShP33f+hDnC"
    "F+Uu2tFfFgxRkdQPk7AKm4MCAwEAAQ=="
    "-----END PUBLIC KEY-----";

RSA::PublicKey publicKey;
publicKey.load(publickey_str);

在 Crypto++ wiki 中,我只找到了如何从文件(.der、.pem)导入/导出密钥。你知道我怎样才能用字符串做同样的事情吗?

编辑:抱歉,我忘了告诉我我缩短了示例的 RSA 公钥。

【问题讨论】:

    标签: c++ rsa crypto++


    【解决方案1】:

    我只知道如何从文件(.der、.pem)导入/导出密钥。你知道我怎样才能用字符串做同样的事情吗?

    在 Crypto++ 中,您可以将一个来源交换为任何其他来源。您可以将FileSource 更改为NetworkSourceStringSourceArraySource 等。

    这同样适用于过滤器。 HexEncoderBase64EncoderHexDecoderBase64Decoder 和所有可互换的过滤器。它不仅限于编码器,您也可以换入加密过滤器、签名过滤器或验证过滤器。因为它们都实现了BufferedTransformation 接口,所以它们可以被换入和换出。

    这同样适用于水槽。您可以将FileSink 更改为NetworkSinkStringSinkArraySink 等。


    您显示的密钥是 PEM 编码的密钥。要在 PEM 中编码和解码,您需要 PEM Pack。它不是库的一部分,因此它可能从您的库副本中丢失。相反,PEM Pack 是由社区维护的附加组件,您必须下载并构建它。

    要使用 PEM Pack,您需要从源代码重建库。设置:

    $ cd cryptopp
    $ wget https://www.cryptopp.com/w/images/5/5a/Pem-pack.zip
    --2017-08-05 16:30:26--  https://www.cryptopp.com/w/images/5/5a/Pem-pack.zip
    Resolving www.cryptopp.com (www.cryptopp.com)... 144.217.231.241
    Connecting to www.cryptopp.com (www.cryptopp.com)|144.217.231.241|:443...
    ...
    2017-08-05 16:30:26 (862 KB/s) - ‘Pem-pack.zip’ saved [20769/20769]
    
    $ unzip -aoq Pem-pack.zip
    $ ls pem*
    pem-com.cpp  pem-create-keys.sh  pem-rd.cpp    pem-verify-keys.sh
    pem-com.h    pem.h               pem-test.cxx  pem-wr.cpp
    

    然后,照常制作:

    $ make distclean
    ...
    
    $ make -j 9
    g++ -DNDEBUG -g2 -O3 -fPIC -march=native -pipe -c cryptlib.cpp
    g++ -DNDEBUG -g2 -O3 -fPIC -march=native -pipe -c cpu.cpp
    g++ -DNDEBUG -g2 -O3 -fPIC -march=native -pipe -c integer.cpp
    ...
    g++ -DNDEBUG -g2 -O3 -fPIC -march=native -pipe -c pem-com.cpp
    g++ -DNDEBUG -g2 -O3 -fPIC -march=native -pipe -c pem-rd.cpp
    g++ -DNDEBUG -g2 -O3 -fPIC -march=native -pipe -c pem-wr.cpp
    ...
    ar r libcryptopp.a cryptlib.o cpu.o integer.o 3way.o ... zdeflate.o zinflate.o zlib.o
    

    注意:我需要修复auto_ptr 警告。我会在今天晚些时候处理它。 这个问题已经解决了。新版本的PEM Pack 可从 wiki 获得。

    现在,您有了 PEM 支持:

    $ nm libcryptopp.a | grep PEM | grep ' T ' | c++filt
    00000000000000a0 T CryptoPP::PEM_WriteLine(CryptoPP::BufferedTransformation&, CryptoPP::SecBlock<unsigned char, CryptoPP::AllocatorWithCleanup<unsigned char, false> > const&)
    00000000000000f0 T CryptoPP::PEM_WriteLine(CryptoPP::BufferedTransformation&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
    0000000000000140 T CryptoPP::PEM_Base64Decode(CryptoPP::BufferedTransformation&, CryptoPP::BufferedTransformation&)
    00000000000004e0 T CryptoPP::PEM_Base64Encode(CryptoPP::BufferedTransformation&, CryptoPP::BufferedTransformation&)
    ...
    

    这是代码。

    $ cat pem-test.cxx
    #include <string>
    #include <iostream>
    
    #include "integer.h"
    #include "rsa.h"
    #include "pem.h"
    using namespace CryptoPP;
    
    int main(int argc, char* argv[])
    {
        const std::string publickey_str =
            "-----BEGIN PUBLIC KEY-----\n"
            "gm6mZA1NTZQJVUk9AGDb6NRngzRlRAgXBTWAispwlqsuHFoCrv02xPm1uxkLyfUq\n"
            "LoA4/EQJ25okjmGkrjgak+XmQIPKmAg94gWAtvRIrLZNmCj/aPeuikmCPXkKtg2b\n"
            "pdB6xzHY0ftGu0l6Vb8zttg7Wfo1kJowjoqCRwo9ex/IKwPXxE3UsugshcZOGdqT\n"
            "6E3B/Vw+JoerL/LfeOU2OYcSFEXsWqjzkrGzEVuKzRnve5RlXyY0gShP33f+hDnC\n"
            "F+Uu2tFfFgxRkdQPk7AKm4MCAwEAAQ==\n"
            "-----END PUBLIC KEY-----\n";
    
        RSA::PublicKey publicKey;
    
        try
        {
            StringSource source(publickey_str, true);
            PEM_Load(source, publicKey);
        }
        catch(const Exception& ex)
        {
            std::cerr << ex.what() << std::endl;
            return 1;
        }
    
        const Integer& e = publicKey.GetPublicExponent();
        std:: cout << e << std::endl;
    
        const Integer& n = publicKey.GetModulus();
        std:: cout << n << std::endl;
    
        return 0;
    }
    

    结果如下:

    $ ./test.exe
    BER decode error
    

    看来您的公钥不正确。我不会在这上面浪费时间,因为我不清楚它是真正的钥匙,还是你编造的随机垃圾。


    关于这个:

    $ unzip -aoq Pem-pack.zip
    $ ls pem*
    pem-com.cpp  pem-create-keys.sh  pem-rd.cpp    pem-verify-keys.sh
    pem-com.h    pem.h               pem-test.cxx  pem-wr.cpp
    

    我使用脚本进行测试。如果需要,您可以删除它们。如果需要,您也可以删除 pem-test.cxx。也不需要。

     $ rm pem-*.sh pem-test.cxx
    

    【讨论】:

      【解决方案2】:

      这就是我将字符串加载到 PublicKey 中的方式

      //Create Cryptopp StringSource From Std::string
      std::string PublicKeyString = "<Your key as std::string value>";
      CryptoPP::StringSource PKeyStringSource(PublicKeyString, true);
      CryptoPP::RSA::PublicKey publicKey;
      publicKey.Load(PKeyStringSource);
      

      查看整个函数以了解详细用法。在这里,我在函数中将密钥作为 std::string 传递以验证签名。 RSA::PublicKey 是从传递给函数的std::string 创建的

      bool Signature::VerifySignature(const std::string &PublicKeyString,
          const std::string &data,
          const std::string &SignatureStr)
      {
          CryptoPP::StringSource PKeyStringSource(PublicKeyString, true);
          CryptoPP::StringSource SignStringSource(SignatureStr, true);
      
          CryptoPP::RSA::PublicKey publicKey;
          publicKey.Load(PKeyStringSource);
      
          // verify message
          bool result = false;
      
          m_verifier.AccessPublicKey().Load(SignStringSource);
      
          CryptoPP::StringSource ss2(SignatureStr + data, true,
              new CryptoPP::SignatureVerificationFilter(m_verifier,
                  new CryptoPP::ArraySink((CryptoPP::byte*)&result,
                      sizeof(result))));
      
          return result;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-10
        • 2018-09-24
        • 2017-09-08
        • 1970-01-01
        • 2020-12-07
        • 2011-03-30
        • 2018-07-03
        • 2013-06-08
        相关资源
        最近更新 更多