gpt4 book ai didi

c++ - 使用公钥 : BER decode error 加密消息

转载 作者:行者123 更新时间:2023-12-01 22:16:22 26 4
gpt4 key购买 nike

我有一个关于使用公钥加密消息的问题。
我想用包含在字符串中的公钥 RSA-4096 加密字符串(让我们说 "test" )。
让我们说:
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm9GgFeJ3DhazIHCVHtNa
Vnu38KBdxViOswyXcJEwQ8yHlQOL6e5He1dxx5uqvnKLR7+gAMzZBXEQlOCrSYi6
nREXGxE4WFTjd+PqLh5bA9DIO8vbsPIsG66zYmFdztmFGn2dl0EUvUiIjGUqwkJA
E5P8ebjsNOdomX1763p8k50AHhIzaUbD+IWAVDEzbew7efOPt5Wj6C5a1kwkv4bX
+viqoC7mFNjQziI+Sg/8yjnT++Zv5fo+JWE6pyXwZCabwgsBYq9Cv2iMC4ZXAFVo
GLYtixok/7rMY6NIe+MIUafrEVbgG8K0YT3U1Jn1knqYV++qtnaqqmcvtoGC1SE6
s8pwiHGRgh+ZG3EwuDZVqJadBdl/CGDz8WnfPs8sSANT1kCJYq3ogp12Fx0axENF
vklCM5jLcm1v6/kyqPYk0fVArH6RT7e5QZCWZXAoxMz1bZe97CZ9+PQGbGLyYrQO
CqBeWkVUEI/NeBoQdifrgok/Ku43LMUrxbTByBSEoXVn4d+3jgN0BS1CmxQslJml
kUPv87OLjzzggQW8lRs3owKQF9TRs9fYljuJSt3f2osYaPhedYx9XdkJNhgbH+AF
47kocpxg6olpOtRaM5cW/0zWSGtVHXfblDO+XFNzddSKLwFyL2Jx8WIfZ6tXa/MP
/aLOyzKX/WADqAEqlHbs3SMCAwEAAQ==
-----END PUBLIC KEY-----

为此,我尝试使用 C++ 中的 CryptoPP 库 (https://www.cryptopp.com/wiki/Keys_and_formats),但是当我尝试读取和解码我的公钥时,我收到以下错误:BER decode error .
这是我正在使用的完整源代码:

#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);
}
}

非常感谢那些可以帮助我理解为什么没有正确读取公钥的人。
对于那些说 golang ,我基本上是在尝试重现以下功能:
func WriteEncryptedWithPublicKeyInformation(filename string, information string, publicKey string) error {

f, err := os.Create(filename)

block, _ := pem.Decode([]byte(publicKey))
if block == nil {
return errors.New("Failed to parse PEM block containing the public key")
}

pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return errors.New("Failed to parse DER encoded public key: " + err.Error())
}

key := pub.(*(rsa.PublicKey))
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, key, []byte(information), nil)
if err != nil {
return err
}

_, err = f.WriteString(b64.StdEncoding.EncodeToString(ciphertext))
if err != nil {
return err

}
f.Close()
return nil
}

在哪里 filename是我的输出文件, information是我要加密的字符串和 publicKey是包含公钥的字符串。

最佳答案

您的程序解码 base64 的方式不正确,函数 RSAFunction::BERDecodePublicKey根据引用

BERDecodePublicKey() the decodes subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header.



您应该使用 X509PublicKey::BERDecodeRSA::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);
}
}

关于c++ - 使用公钥 : BER decode error 加密消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59894378/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com