2016-06-14 66 views
2

我有用於RSA算法的n,d,e。但是,我想使用private_key加密某些字符串,生成USER_CERTIFICATION,並使用public_key爲用戶解密並獲取字符串。我知道,如果我這樣做,該字符串可以很容易被人解密,但安全性我關心的所有,我只是需要一個任何人,除非我可以生成USER_CERTIFICATION使用加密++ RSA :: PublicKey來解密密文

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

但解密代碼拋出一個異常: 「類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可以做到這一點嗎?

+0

你是怎麼做出來嗎?任何驚喜仍然存在? – jww

回答

2

我想用PRIVATE_KEY加密一些字符串

通常,當你問加密用私鑰,你想要的是與恢復(PSSR)方案的Probablistic簽名。順便說一句,加密用私鑰有效的密碼變換:)

cryptlib.h header被描述爲這個圖書館提供一個統一的接口抽象基類。所有Crypto ++簽署者和驗證者都遵守PK_SignatureScheme接口。簽名者進一步實施PK_Signer,而驗證者進一步實施PK_Verifier

的加密+ RSA的物體看起來像這樣:

​​3210

的加密+拉賓的物體看起來像這樣:

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

的加密+拉賓 - 威廉姆斯的物體看起來像這樣:

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

這些對象是一致的,您可以將它們交換出來。

順便說一句,你應該看看拉賓威廉姆斯,看看它是否符合你的需求。另見伯恩斯坦的RSA signatures and Rabin–Williams signatures: the state of the art


我使用CryptoPP,用於編碼的代碼工作正常...

廢了。你使用的指數是衆所周知的,所以你在做什麼沒有真正的安全性。有許多方法可以提高安全性,但聽起來您想要PSSR。

下面是使用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); 

...但解密代碼拋出一個異常: 「類CryptoPP :: InvertibleRSAFunction:缺少必需的參數 'Prime1'」

沒錯,加密與私營密鑰不是有效的密碼轉換。我敢肯定解密用公鑰有效的,無論是:)


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

+0

SignatureWithRecovery有效,但無法處理大於128字節的郵件。將長消息分割成許多128字節塊似乎不是一個好主意。現在我使用'a_exp_b_mod_c(message,d,n)'來自己完成編碼。 – aj3423

+0

@ aj3423 - 只要沒有驚喜......你的信息仍然太大。 'a_exp_b_mod_c'靜靜地截斷它。如果您執行反向轉換,那麼您將收到截斷的消息。查看[原始RSA](http://www.cryptopp.com/wiki/Raw_RSA),並檢查您恢復的消息(相關部分是[私鑰加密](http://www.cryptopp.com/wiki)/Raw_RSA#Private_Key_Encryption))。爲了避免截斷:是否可以增加模數的大小或使用較小的消息? – jww

+0

@ aj3423 - 還要確保你*真的*想放棄對簽名的隨機化。引用的伯恩斯坦論文討論了爲什麼要在第5部分中隨機化一個簽名。自1979年以來,對非隨機簽名的攻擊一直存在。 – jww

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

@ jwwYes,但在我看來,他想要做的是典型的compute-hash-of-msg-> encrypt-hash-with-private-key。然後,收件人可以通過使用發件人的公鑰驗證msg的真實性,如果該密鑰經過CA驗證且可信。 –