C++ 使用加密++;RSA::用于解密密码文本的公钥

C++ 使用加密++;RSA::用于解密密码文本的公钥,c++,rsa,private-key,crypto++,C++,Rsa,Private Key,Crypto++,我有n,d,e的RSA算法。但是,我想使用私钥加密一些字符串,生成用户证书,并使用公钥为用户解密并获取字符串。我知道如果我这样做,任何人都可以轻松解密字符串,但安全性根本不是我关心的问题,我只需要除了我之外没有人可以生成用户证书 我使用的是CryptoPP,编码代码很好: Integer _n(...), _e(...), _d(...); AutoSeededRandomPool rng; RSA::PrivateKey k; k.Initialize(_n, _e, _d); RSAES_P

我有n,d,e的RSA算法。但是,我想使用私钥加密一些字符串,生成用户证书,并使用公钥为用户解密并获取字符串。我知道如果我这样做,任何人都可以轻松解密字符串,但安全性根本不是我关心的问题,我只需要除了我之外没有人可以生成用户证书

我使用的是CryptoPP,编码代码很好:

Integer _n(...), _e(...), _d(...);
AutoSeededRandomPool rng;
RSA::PrivateKey k;
k.Initialize(_n, _e, _d);
RSAES_PKCS1v15_Encryptor enc(k);
std::string cipher;
StringSource ss1( plain, true,
    new PK_EncryptorFilter( rng, enc,
        new StringSink( cipher )) // PK_EncryptorFilter
    ); // StringSource
但是解密代码引发了一个异常:“ClassCryptoPP::InvertibleRSAFunction:缺少必需的参数'Prime1'”

是否可以使用CryptoPP执行此操作

我想用私钥加密一些字符串

通常,当您要求使用私钥进行加密时,您需要的是带恢复的概率签名(PSSR)方案。顺便说一下,使用私钥加密不是有效的加密转换:)

将描述为抽象基类,这些抽象基类为该库提供统一接口。所有Crypto++签名者和验证者都遵守该接口。签名者进一步实现,而验证者进一步实现

Crypto++RSA对象看起来是这样的:

RSASS<PSSR, SHA256>::Signer signer;
RSASS<PSSR, SHA256>::Verifier verifier;
RabinSS<PSSR, SHA256>::Signer signer;
RabinSS<PSSR, SHA256>::Verifier verifier;
RWSS<PSSR, SHA256>::Signer signer;
RWSS<PSSR, SHA256>::Verifier verifier;

这是你拨入一些资料时的验证码。请注意,您不需要,因此可以在需要时使用
NullRNG()

Integer n(...), e(...);
RSA::PublicKey key(n,e);
RSASS<PSSR, SHA256>::Verifier verifier(key);

////////////////////////////////////////////////
// Verify and Recover
SecByteBlock recovered(
    verifier.MaxRecoverableLengthFromSignatureLength(signatureLen)
);

DecodingResult result = verifier.RecoverMessage(recovered, NULL, 0, signature, signatureLen);

if (!result.isValidCoding) {
    throw Exception(Exception::OTHER_ERROR, "Invalid Signature");
}

////////////////////////////////////////////////
// Use recovered message
//  MaxSignatureLength is likely larger than messageLength
recovered.resize(result.messageLength);
整数n(…),e(…);
RSA::公钥(n,e);
RSASS::验证器验证器(密钥);
////////////////////////////////////////////////
//验证和恢复
已恢复SecByteBlock(
验证器.SignatureLength的最大可恢复长度(SignatureLength)
);
DecodingResult=verifier.RecoverMessage(已恢复,NULL,0,签名,signatureLen);
如果(!result.isvalidCode){
抛出异常(异常::其他_错误,“无效签名”);
}
////////////////////////////////////////////////
//使用恢复的邮件
//MaxSignatureLength可能大于messageLength
恢复。调整大小(result.messageLength);

。。。但是解密代码引发了一个异常:“ClassCryptoPP::InvertibleRSAFunction:缺少必需的参数'Prime1'”

是的,使用私钥加密不是有效的加密转换。我很确定用公钥解密是无效的:)



我不打算提供用于加密和解密的代码,因为我认为您不需要它。但是你可以在Crypto++wiki上找到它。

那么,你想用你的私钥签署一封邮件吗?这个链接有一个例子,也许有帮助(下面的代码和链接)。还请注意,并非所有签名都是加密。例如,比特币使用的ECDSA使用一个签名操作,将随机数作为一个输入,签名时不进行加密


@jwwYes,但在我看来,他想要做的是msg->encrypt的经典计算哈希——使用私钥进行哈希。然后,如果发件人的公钥经过CA验证且受信任,则收件人可以使用该公钥验证消息的真实性。SignatureWithRecovery可以工作,但它无法处理大于128字节的消息。将长消息拆分为许多128字节的块似乎不是一个好主意。现在我自己用
a\u exp\u b\u mod\u c(message,d,n)
来做编码。@aj3423-这样就没有什么意外了。。。您的消息仍然太大<代码>a_exp_b_mod_c自动截断它。如果执行反向转换,则会返回一条截断的消息。签出并检查您恢复的邮件(相关部分为)。为了避免截断:是否可以增加模的大小或使用更小的消息?@aj3423-还要确保您确实希望放弃对签名的随机化。引用的Bernstein论文讨论了为什么要在第5节中将签名随机化。针对非随机签名的攻击自1979年以来就一直存在。是的,我必须将消息分成244个字节,用于pkcs1v15填充,我认为244仍然优于128个字节。稍后我将尝试
ApplyFunction
+
CalculateInverse
,谢谢。@aj3423-听起来不错。你可能还想在Google Scholar上搜索:看看有哪些选择适合你的需要。
Integer n(...), e(...), d(...);
RSA::PrivateKey key(n,e,d);
RSASS<PSSR, SHA256>::Signer signer(key);

////////////////////////////////////////////////
// Sign and Encode
SecByteBlock signature(signer.MaxSignatureLength(messageLen));

AutoSeededRandomPool rng;
size_t signatureLen = signer.SignMessageWithRecovery(rng, message, messageLen, NULL, 0, signature);

// Resize now we know the true size of the signature
signature.resize(signatureLen);
Integer n(...), e(...);
RSA::PublicKey key(n,e);
RSASS<PSSR, SHA256>::Verifier verifier(key);

////////////////////////////////////////////////
// Verify and Recover
SecByteBlock recovered(
    verifier.MaxRecoverableLengthFromSignatureLength(signatureLen)
);

DecodingResult result = verifier.RecoverMessage(recovered, NULL, 0, signature, signatureLen);

if (!result.isValidCoding) {
    throw Exception(Exception::OTHER_ERROR, "Invalid Signature");
}

////////////////////////////////////////////////
// Use recovered message
//  MaxSignatureLength is likely larger than messageLength
recovered.resize(result.messageLength);
void Sign()
{
string strContents = "A message to be signed";
//FileSource("tobesigned.dat", true, new StringSink(strContents));

AutoSeededRandomPool rng;

//Read private key
CryptoPP::ByteQueue bytes;
FileSource file("privkey.txt", true, new Base64Decoder);
file.TransferTo(bytes);
bytes.MessageEnd();
RSA::PrivateKey privateKey;
privateKey.Load(bytes);

//Sign message
RSASSA_PKCS1v15_SHA_Signer privkey(privateKey);
SecByteBlock sbbSignature(privkey.SignatureLength());
privkey.SignMessage(
   rng,
   (byte const*) strContents.data(),
   strContents.size(),
   sbbSignature);

   //Save result
   FileSink sink("signed.dat");
   sink.Put((byte const*) strContents.data(), strContents.size());
   FileSink sinksig("sig.dat");
   sinksig.Put(sbbSignature, sbbSignature.size());
}