从字符串 Crypto++ 导入 RSA public/private 密钥
Import RSA public/private key from a string Crypto++
我想直接从字符串变量中导入一个 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 中,我只找到如何 import/export 键 from/to 文件(.der、.pem)。你知道我怎样才能用字符串做同样的事情吗?
编辑:抱歉,我忘了告诉我我为示例缩短了 RSA public 密钥。
I only find how to import/export keys from/to files (.der, .pem). Do you know how can i do the same thing with a string ?
在 Crypto++ 中,您可以将一个来源换成任何其他来源。您可以将 FileSource
更改为 NetworkSource
、StringSource
、ArraySource
等
这同样适用于过滤器。 HexEncoder
、Base64Encoder
、HexDecoder
、Base64Decoder
和所有可互换的过滤器。它不仅限于编码器,您也可以换入加密过滤器、签名过滤器或验证过滤器。它们可以换入和换出,因为它们都实现了 BufferedTransformation
接口。
同样适用于水槽。您可以将 FileSink
更改为 NetworkSink
、StringSink
、ArraySink
等
您显示的密钥是 PEM 编码密钥。要在 PEM 中编码和解码,您需要 PEM Pack。它不是图书馆本身的一部分,因此您的图书馆副本中可能会丢失它。相反,PEM 包是由社区维护的附加组件,您必须下载并构建它。
要使用 PEM 包,您需要从源重建库。设置:
$ 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
您的 public 密钥似乎有问题。我不会在上面浪费时间,因为我不清楚它是真的钥匙,还是你随意编造的垃圾。
对此:
$ 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
这就是我将字符串加载到 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;
}
我想直接从字符串变量中导入一个 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 中,我只找到如何 import/export 键 from/to 文件(.der、.pem)。你知道我怎样才能用字符串做同样的事情吗?
编辑:抱歉,我忘了告诉我我为示例缩短了 RSA public 密钥。
I only find how to import/export keys from/to files (.der, .pem). Do you know how can i do the same thing with a string ?
在 Crypto++ 中,您可以将一个来源换成任何其他来源。您可以将 FileSource
更改为 NetworkSource
、StringSource
、ArraySource
等
这同样适用于过滤器。 HexEncoder
、Base64Encoder
、HexDecoder
、Base64Decoder
和所有可互换的过滤器。它不仅限于编码器,您也可以换入加密过滤器、签名过滤器或验证过滤器。它们可以换入和换出,因为它们都实现了 BufferedTransformation
接口。
同样适用于水槽。您可以将 FileSink
更改为 NetworkSink
、StringSink
、ArraySink
等
您显示的密钥是 PEM 编码密钥。要在 PEM 中编码和解码,您需要 PEM Pack。它不是图书馆本身的一部分,因此您的图书馆副本中可能会丢失它。相反,PEM 包是由社区维护的附加组件,您必须下载并构建它。
要使用 PEM 包,您需要从源重建库。设置:
$ 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
注意:我需要修复 这已得到修复。 PEM Pack 的新版本可从 wiki 获得。auto_ptr
警告。我会在今天晚些时候解决。
现在,您拥有 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
您的 public 密钥似乎有问题。我不会在上面浪费时间,因为我不清楚它是真的钥匙,还是你随意编造的垃圾。
对此:
$ 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
这就是我将字符串加载到 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;
}