使用Crypto++ RSA::PublicKey解密密文

Use Crypto++ RSA::PublicKey to decrypt cipher text

我有 RSA 算法的 n、d、e。但是,我想用private_key加密一些字符串,生成USER_CERTIFICATION,然后用public_key让用户解密得到字符串。我知道如果我这样做,任何人都可以轻松解密该字符串,但安全性根本不是我关心的,我只需要除了我以外没有人可以生成USER_CERTIFICATION

我正在使用 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

但解密代码抛出异常:"class CryptoPP::InvertibleRSAFunction: Missing required parameter 'Prime1'"

Integer _n(...), _e(...);

AutoSeededRandomPool rng;
RSA::PublicKey k;
k.Initialize(_n, _e);
RSAES_PKCS1v15_Decryptor dec(k);
std::string plain;
StringSource ss1( cipher, true,
    new PK_DecryptorFilter( rng, dec,
        new StringSink( plain ))
    ); // StringSource

可以用 CryptoPP 做到这一点吗?

I want to use private_key to encrypt some string

通常,当您要求使用私钥加密时,您想要的是概率签名恢复(PSSR)方案.顺便说一句,用私钥加密不是有效的密码转换:)

cryptlib.h header is described as Abstract base classes that provide a uniform interface to this library. All Crypto++ Signers and Verifiers adhere to the PK_SignatureScheme interface. Signers further implement PK_Signer, while Verifiers further implement PK_Verifier.

Crypto++ RSA 对象如下所示:

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

Crypto++ Rabin 对象如下所示:

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

Crypto++ Rabin-Williams 对象看起来像这样:

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

对象是一致的,您可以将它们换入换出。

顺便说一下,您应该查看 Rabin-Williams 是否符合您的需求。另见 Bernstein 的 RSA signatures and Rabin–Williams signatures: the state of the art.


I'm using CryptoPP, the code for encoding works fine ...

报废它。您使用的指数是众所周知的,因此您所做的事情没有真正的安全性。有很多方法可以提高安全性,但听起来您更想要一个 PSSR。

这里有两个使用 wiki 中 RSA 的 PSSR 的例子:

这是 RSA Probabilistic Signature Scheme with Recovery 的签名者代码,其中包含您拨入的一些内容。请注意,您需要真正的 RandomNumberGenerator,因为签名是随机的.

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

这里是 RSA Probabilistic Signature Scheme with Recovery 的验证码,其中包含您拨入的一些内容。请注意,您不需要 RandomNumberGenerator,因此您可以如果某处需要,请使用 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);

... but the decryption code throws an exception: "class CryptoPP::InvertibleRSAFunction: Missing required parameter 'Prime1'"

是的,使用私钥加密 不是有效的密码转换。我很确定 使用 public 密钥解密 not 有效,或者: )


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

那么,您想用您的私钥签署消息吗?这个 link 有一个例子,也许它有帮助(下面的代码和 link)。另请注意,并非所有签名都是加密的。例如,比特币使用的 ECDSA 使用一种将随机数作为输入的签名操作,签名过程中不进行任何加密。

https://www.cryptopp.com/wiki/User_Guide:_rsa.h

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