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

时间:2016-06-14 06:04:02

标签: c++ rsa private-key crypto++

我有用于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:缺少必需参数'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执行此操作?

2 个答案:

答案 0 :(得分:2)

  

我想使用private_key来加密某些字符串

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

cryptlib.h header被描述为抽象基类,为此库提供统一的接口。所有Crypto ++签名者和验证者都遵守PK_SignatureScheme接口。签名者进一步实施PK_Signer,而验证者进一步实施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,看看它是否符合你的需求。另请参阅伯恩斯坦的RSA signatures and Rabin–Williams signatures: the state of the art

  

我使用CryptoPP,编码代码工作得很好......

废弃它。您使用的指数是众所周知的,因此您所做的事情并没有真正的安全性。有一些方法可以提高安全性,但听起来你想要一个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);
  

...但解密代码抛出异常:&#34;类CryptoPP :: InvertibleRSAFunction:缺少必需参数&#39; Prime1&#39;&#34;

是的,使用私钥进行加密 有效的加密转换。我非常确定使用公钥解密 有效,或者:)

我不会提供加密和解密的代码,因为我不相信你需要它。但你可以在Crypto ++ wiki上的RSA Encryption Schemes找到它。

答案 1 :(得分:0)

那么,您想用私钥签名邮件吗?这个链接有一个例子,也许它有帮助(下面的代码和链接)。另请注意,并非所有签名都是加密。例如,比特币使用的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());
}