C++ 使用公钥加密消息:BER解码错误
关于使用公钥加密消息,我有一个问题。 我想用字符串中包含的公钥RSA-4096加密字符串(比如说C++ 使用公钥加密消息:BER解码错误,c++,c++11,go,cryptography,crypto++,C++,C++11,Go,Cryptography,Crypto++,关于使用公钥加密消息,我有一个问题。 我想用字符串中包含的公钥RSA-4096加密字符串(比如说“test”)。 让我们说: ----开始公钥----- MIICIJANBGKQHKIG9W0BAQEFAOCAG8AMICCGKCAGEAM9GGFEJ3DHAZIHCVHTNA VNU38KBDXVIOSWYXCJEWQ8YHLQOL6E5HE1DX5UQVNKLR7+GAMZZBXEQLOCRSY6 nREXGxE4WFTjd+PQLH5BA9DIO8VBSPISG66ZYMFZTMFGN2D
“test”
)。
让我们说:
----开始公钥-----
MIICIJANBGKQHKIG9W0BAQEFAOCAG8AMICCGKCAGEAM9GGFEJ3DHAZIHCVHTNA
VNU38KBDXVIOSWYXCJEWQ8YHLQOL6E5HE1DX5UQVNKLR7+GAMZZBXEQLOCRSY6
nREXGxE4WFTjd+PQLH5BA9DIO8VBSPISG66ZYMFZTMFGN2DL0EUVUIIJGUQWKJA
E5P8ebjsNOdomX1763p8k50AHhIzaUbD+IWAVDEZBEW7EFOPT5WJ6C5A1KW4BX
+viqoC7mFNjQziI+Sg/8yjnT++Zv5fo+JWE6pyXwZCabwgsBYq9Cv2iMC4ZXAFVo
GLYtixok/7rMY6NIe+MiuafrevBG8K0YT3U1JN1KNQYV++qtnaqqmcvtoGC1SE6
s8pwiHGRgh+ZG3EwuDZVqJadBdl/CGDZ8WNFS8SSANT1KCJYQ3OGP12Fx0AXENF
vklCM5jLcm1v6/kyqPYk0fVArH6RT7e5QZCWZXAoxMz1bZe97CZ9+PQGbGLyYrQO
CqBeWkVUEI/NeBoQdifrgok/Ku43LMUrxbTByBSEoXVn4d+3jgN0BS1CmxQslJml
kUPv87OLjzzggQW8lRs3owKQF9TRs9fYljuJSt3f2osYaPhedYx9XdkJNhgbH+AF
47kocpxg6olpOtRaM5cW/0zWSGtVHXfblDO+XFNzddSKLwFyL2Jx8WIfZ6tXa/MP
/aLOyzKX/WADQAEQLHBS3SMCAWAAQ==
-----结束公钥------
这样,我尝试使用C++中的CytoTopp库,但是当我尝试读取和解码我的公钥时,我得到以下错误:<代码> BER解码错误< /C>。 以下是我正在使用的完整源代码:
#include <string>
#include <iomanip>
#include <iostream>
#include <exception>
#include <fstream>
#include <cryptopp/queue.h>
using CryptoPP::ByteQueue;
#include <cryptopp/filters.h>
using CryptoPP::Redirector;
#include <cryptopp/files.h>
using CryptoPP::FileSource;
using CryptoPP::FileSink;
#include <cryptopp/cryptlib.h>
using CryptoPP::PrivateKey;
using CryptoPP::PublicKey;
using CryptoPP::BufferedTransformation;
#include <cryptopp/sha.h>
#include <cryptopp/rsa.h>
using CryptoPP::RSA;
#include <cryptopp/base64.h>
using CryptoPP::Base64Encoder;
using CryptoPP::Base64Decoder;
#include <cryptopp/osrng.h>
using CryptoPP::AutoSeededRandomPool;
using namespace std;
int main(int argc, char** argv) {
ByteQueue queue;
string RSA_PUBLIC_KEY ="-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm9GgFeJ3DhazIHCVHtNaVnu38KBdxViOswyXcJEwQ8yHlQOL6e5He1dxx5uqvnKLR7+gAMzZBXEQlOCrSYi6nREXGxE4WFTjd+PqLh5bA9DIO8vbsPIsG66zYmFdztmFGn2dl0EUvUiIjGUqwkJAE5P8ebjsNOdomX1763p8k50AHhIzaUbD+IWAVDEzbew7efOPt5Wj6C5a1kwkv4bX+viqoC7mFNjQziI+Sg/8yjnT++Zv5fo+JWE6pyXwZCabwgsBYq9Cv2iMC4ZXAFVoGLYtixok/7rMY6NIe+MIUafrEVbgG8K0YT3U1Jn1knqYV++qtnaqqmcvtoGC1SE6s8pwiHGRgh+ZG3EwuDZVqJadBdl/CGDz8WnfPs8sSANT1kCJYq3ogp12Fx0axENFvklCM5jLcm1v6/kyqPYk0fVArH6RT7e5QZCWZXAoxMz1bZe97CZ9+PQGbGLyYrQOCqBeWkVUEI/NeBoQdifrgok/Ku43LMUrxbTByBSEoXVn4d+3jgN0BS1CmxQslJmlkUPv87OLjzzggQW8lRs3owKQF9TRs9fYljuJSt3f2osYaPhedYx9XdkJNhgbH+AF47kocpxg6olpOtRaM5cW/0zWSGtVHXfblDO+XFNzddSKLwFyL2Jx8WIfZ6tXa/MP/aLOyzKX/WADqAEqlHbs3SMCAwEAAQ==-----END PUBLIC KEY-----";
static string HEADER = "-----BEGIN PUBLIC KEY-----";
static string FOOTER = "-----END PUBLIC KEY-----";
size_t pos1 = RSA_PUBLIC_KEY.find(HEADER);
if(pos1 == string::npos) throw runtime_error("PEM header not found");
size_t pos2 = RSA_PUBLIC_KEY.find(FOOTER, pos1+1);
if(pos2 == string::npos) throw runtime_error("PEM footer not found");
// Start position and length
pos1 = pos1 + HEADER.length();
pos2 = pos2 - pos1;
string keystr = RSA_PUBLIC_KEY.substr(pos1, pos2);
/*Base64Encoder decoder;
decoder.Attach(new Redirector(queue));*/
queue.Put((const byte*)keystr.data(), keystr.length());
queue.MessageEnd();
cout << keystr << endl;
try {
RSA::PublicKey public_key;
public_key.BERDecodePublicKey(queue, false /*paramsPresent*/, queue.MaxRetrievable());
if(queue.IsEmpty()) {
cerr << "The queue is empty...";
}
AutoSeededRandomPool prng;
bool valid = public_key.Validate(prng, 3);
if(!valid) cerr << "RSA public key is not valid" << endl;
cout << "N:" << public_key.GetModulus() << endl;
cout << "E:" << public_key.GetPublicExponent() << endl;
} catch (exception& e) {
printf( "Caught exception: %s\n", e.what() );
exit (1);
}
}
<> > <代码>文件名< /代码>是我的输出文件,<代码>信息<代码>是我要加密的字符串,<代码>公钥< /代码>是包含公钥的字符串。 < p>我没有看到你在中间解码基64。BER是一种二进制格式,您首先必须将其转换为二进制才能读取。您的程序解码base64的方式不正确,并且根据参考,函数
rsaffunction::BERDecodePublicKey
BERDecodePublicKey()解码subjectPublicKeyInfo的subjectPublicKey部分,不带位字符串头
您应该使用X509PublicKey::BERDecode
函数,因为类RSA::PublicKey
继承自X509PublicKey
试试这个程序,它应该可以工作
#include <string>
#include <iomanip>
#include <iostream>
#include <exception>
#include <fstream>
#include <cryptopp/queue.h>
using CryptoPP::ByteQueue;
#include <cryptopp/filters.h>
using CryptoPP::Redirector;
#include <cryptopp/files.h>
using CryptoPP::FileSource;
using CryptoPP::FileSink;
#include <cryptopp/cryptlib.h>
using CryptoPP::PrivateKey;
using CryptoPP::PublicKey;
using CryptoPP::BufferedTransformation;
#include <cryptopp/sha.h>
#include <cryptopp/rsa.h>
#include <cryptopp/asn.h>
using CryptoPP::RSA;
#include <cryptopp/base64.h>
using CryptoPP::Base64Encoder;
using CryptoPP::Base64Decoder;
#include <cryptopp/osrng.h>
using CryptoPP::AutoSeededRandomPool;
using namespace std;
int main() {
ByteQueue queue;
string RSA_PUBLIC_KEY ="-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm9GgFeJ3DhazIHCVHtNaVnu38KBdxViOswyXcJEwQ8yHlQOL6e5He1dxx5uqvnKLR7+gAMzZBXEQlOCrSYi6nREXGxE4WFTjd+PqLh5bA9DIO8vbsPIsG66zYmFdztmFGn2dl0EUvUiIjGUqwkJAE5P8ebjsNOdomX1763p8k50AHhIzaUbD+IWAVDEzbew7efOPt5Wj6C5a1kwkv4bX+viqoC7mFNjQziI+Sg/8yjnT++Zv5fo+JWE6pyXwZCabwgsBYq9Cv2iMC4ZXAFVoGLYtixok/7rMY6NIe+MIUafrEVbgG8K0YT3U1Jn1knqYV++qtnaqqmcvtoGC1SE6s8pwiHGRgh+ZG3EwuDZVqJadBdl/CGDz8WnfPs8sSANT1kCJYq3ogp12Fx0axENFvklCM5jLcm1v6/kyqPYk0fVArH6RT7e5QZCWZXAoxMz1bZe97CZ9+PQGbGLyYrQOCqBeWkVUEI/NeBoQdifrgok/Ku43LMUrxbTByBSEoXVn4d+3jgN0BS1CmxQslJmlkUPv87OLjzzggQW8lRs3owKQF9TRs9fYljuJSt3f2osYaPhedYx9XdkJNhgbH+AF47kocpxg6olpOtRaM5cW/0zWSGtVHXfblDO+XFNzddSKLwFyL2Jx8WIfZ6tXa/MP/aLOyzKX/WADqAEqlHbs3SMCAwEAAQ==-----END PUBLIC KEY-----";
static string HEADER = "-----BEGIN PUBLIC KEY-----";
static string FOOTER = "-----END PUBLIC KEY-----";
size_t pos1 = RSA_PUBLIC_KEY.find(HEADER);
if(pos1 == string::npos) throw runtime_error("PEM header not found");
size_t pos2 = RSA_PUBLIC_KEY.find(FOOTER, pos1+1);
if(pos2 == string::npos) throw runtime_error("PEM footer not found");
// Start position and length
pos1 = pos1 + HEADER.length();
pos2 = pos2 - pos1;
string keystr = RSA_PUBLIC_KEY.substr(pos1, pos2);
CryptoPP::StringSource ss{keystr.c_str(), true};
Base64Decoder decoder;
decoder.Attach(new Redirector(queue));
ss.TransferTo(decoder);
decoder.MessageEnd();
cout << keystr << endl;
try {
RSA::PublicKey public_key;
if(queue.IsEmpty()) {
cerr << "The queue is empty...";
}
public_key.BERDecode(queue);
AutoSeededRandomPool prng;
bool valid = public_key.Validate(prng, 3);
if(!valid) cerr << "RSA public key is not valid" << endl;
cout << "N:" << public_key.GetModulus() << endl;
cout << "E:" << public_key.GetPublicExponent() << endl;
} catch (exception& e) {
printf( "Caught exception: %s\n", e.what() );
exit (1);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
使用CryptoPP::ByteQueue;
#包括
使用CryptoPP::重定向器;
#包括
使用CryptoPP::FileSource;
使用CryptoPP::FileLink;
#包括
使用CryptoPP::PrivateKey;
使用CryptoPP::公钥;
使用CryptoPP::BufferedTransformation;
#包括
#包括
#包括
使用CryptoPP::RSA;
#包括
使用CryptoPP::Base64编码器;
使用CryptoPP::Base64解码器;
#包括
使用CryptoPP::AutoSeedRandomPool;
使用名称空间std;
int main(){
字节队列;
字符串RSA_公钥="-----公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共钥匙,公共Fvogly2.该文给出了一个简单的概念,一个简单的概念,一个简单的概念,一个简单的概念,一个简单的概念,一个简单的概念,一个简单的概念,一个新的概念,一个新的概念,一个新的概念,一个新的概念,一个简单的概念,一个简单的概念,一个简单的概念,一个简单的概念,一个新的概念,一个概念,一个新的概念,一个框架,一个新的概念,一个框架,一个框架,一个框架,一个框架,一个框架,一个框架,一个框架,一个框架,一个框架,一个框架,一个框架一个框架,一个框架一个框架,一个框架一个框架,一个框架一个框架,一个框架一个框架一个框架一个框架一个框架一个框架,一个框架一个框架一个框架一个框架一个框架一个框架一个框架一个框架一个框架一个框架一个KOCPXG6OLPOTRAM5CW/0zWSGtVHXfblDO+XFNzddSKLwFyL2Jx8WIfZ6tXa/MP/aLOyzKX/WADQAEQLHBS3SMCAWAAQ==----结束公钥------”;
静态字符串头=“----开始公钥------”;
静态字符串页脚=“------结束公钥------”;
size\t pos1=RSA\u PUBLIC\u KEY.find(头);
if(pos1==string::npos)抛出运行时_错误(“找不到PEM头”);
size\u t pos2=RSA\u PUBLIC\u KEY.find(页脚,pos1+1);
if(pos2==string::npos)抛出运行时_错误(“找不到PEM页脚”);
//起始位置和长度
pos1=pos1+HEADER.length();
pos2=pos2-pos1;
字符串keystr=RSA\u PUBLIC\u KEY.substr(pos1,pos2);
CryptoPP::StringSource ss{keystr.c_str(),true};
Base64解码器;
附加(新重定向器(队列));
传输到(解码器);
decoder.MessageEnd();
库特
#include <string>
#include <iomanip>
#include <iostream>
#include <exception>
#include <fstream>
#include <cryptopp/queue.h>
using CryptoPP::ByteQueue;
#include <cryptopp/filters.h>
using CryptoPP::Redirector;
#include <cryptopp/files.h>
using CryptoPP::FileSource;
using CryptoPP::FileSink;
#include <cryptopp/cryptlib.h>
using CryptoPP::PrivateKey;
using CryptoPP::PublicKey;
using CryptoPP::BufferedTransformation;
#include <cryptopp/sha.h>
#include <cryptopp/rsa.h>
#include <cryptopp/asn.h>
using CryptoPP::RSA;
#include <cryptopp/base64.h>
using CryptoPP::Base64Encoder;
using CryptoPP::Base64Decoder;
#include <cryptopp/osrng.h>
using CryptoPP::AutoSeededRandomPool;
using namespace std;
int main() {
ByteQueue queue;
string RSA_PUBLIC_KEY ="-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm9GgFeJ3DhazIHCVHtNaVnu38KBdxViOswyXcJEwQ8yHlQOL6e5He1dxx5uqvnKLR7+gAMzZBXEQlOCrSYi6nREXGxE4WFTjd+PqLh5bA9DIO8vbsPIsG66zYmFdztmFGn2dl0EUvUiIjGUqwkJAE5P8ebjsNOdomX1763p8k50AHhIzaUbD+IWAVDEzbew7efOPt5Wj6C5a1kwkv4bX+viqoC7mFNjQziI+Sg/8yjnT++Zv5fo+JWE6pyXwZCabwgsBYq9Cv2iMC4ZXAFVoGLYtixok/7rMY6NIe+MIUafrEVbgG8K0YT3U1Jn1knqYV++qtnaqqmcvtoGC1SE6s8pwiHGRgh+ZG3EwuDZVqJadBdl/CGDz8WnfPs8sSANT1kCJYq3ogp12Fx0axENFvklCM5jLcm1v6/kyqPYk0fVArH6RT7e5QZCWZXAoxMz1bZe97CZ9+PQGbGLyYrQOCqBeWkVUEI/NeBoQdifrgok/Ku43LMUrxbTByBSEoXVn4d+3jgN0BS1CmxQslJmlkUPv87OLjzzggQW8lRs3owKQF9TRs9fYljuJSt3f2osYaPhedYx9XdkJNhgbH+AF47kocpxg6olpOtRaM5cW/0zWSGtVHXfblDO+XFNzddSKLwFyL2Jx8WIfZ6tXa/MP/aLOyzKX/WADqAEqlHbs3SMCAwEAAQ==-----END PUBLIC KEY-----";
static string HEADER = "-----BEGIN PUBLIC KEY-----";
static string FOOTER = "-----END PUBLIC KEY-----";
size_t pos1 = RSA_PUBLIC_KEY.find(HEADER);
if(pos1 == string::npos) throw runtime_error("PEM header not found");
size_t pos2 = RSA_PUBLIC_KEY.find(FOOTER, pos1+1);
if(pos2 == string::npos) throw runtime_error("PEM footer not found");
// Start position and length
pos1 = pos1 + HEADER.length();
pos2 = pos2 - pos1;
string keystr = RSA_PUBLIC_KEY.substr(pos1, pos2);
CryptoPP::StringSource ss{keystr.c_str(), true};
Base64Decoder decoder;
decoder.Attach(new Redirector(queue));
ss.TransferTo(decoder);
decoder.MessageEnd();
cout << keystr << endl;
try {
RSA::PublicKey public_key;
if(queue.IsEmpty()) {
cerr << "The queue is empty...";
}
public_key.BERDecode(queue);
AutoSeededRandomPool prng;
bool valid = public_key.Validate(prng, 3);
if(!valid) cerr << "RSA public key is not valid" << endl;
cout << "N:" << public_key.GetModulus() << endl;
cout << "E:" << public_key.GetPublicExponent() << endl;
} catch (exception& e) {
printf( "Caught exception: %s\n", e.what() );
exit (1);
}
}