2016-06-14 19 views
2

Ich habe die n, d, e für RSA-Algorithmus. Ich möchte jedoch private_key verwenden, um eine Zeichenfolge zu verschlüsseln, USER_CERTIFICATION zu generieren und public_key für Benutzer verwenden, um es zu entschlüsseln und die Zeichenfolge abzurufen. Ich weiß, wenn ich dies tun, kann die Zeichenfolge von jedermann leicht entschlüsselt werden, aber die Sicherheit ist nicht mein Anliegen überhaupt, ich brauche nur, dass niemand außer mir die USER_CERTIFICATIONVerwenden Sie Crypto ++ RSA :: PublicKey, um verschlüsselten Text zu entschlüsseln

erzeugen kann ich bin mit CryptoPP, funktioniert der Code für die Codierung fein:

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 

aber der Entschlüsselungscode löst eine Ausnahme: "Klasse CryptoPP :: InvertibleRSAFunction: Fehlende erforderlichen 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 

Ist es möglich, dies mit CryptoPP zu tun?

+0

Wie hast du hier ausmachen? Irgendwelche Überraschungen bleiben? – jww

Antwort

2

Ich möchte private_key verwenden, um einige Zeichenfolge

Regel zu verschlüsseln, wenn Sie sich für verschlüsseln mit dem privaten Schlüssel fragen, was Sie wollen, ist ein Probablistic Signatur mit Recovery (PSSR) Schema . By the way, ist verschlüsseln mit dem privaten Schlüsselnicht eine gültige Verschlüsselungstransformation :)

Die cryptlib.h header als abstrakte Basisklassen beschrieben, die eine einheitliche Schnittstelle zu dieser Bibliothek zur Verfügung stellen. Alle Crypto ++ - Unterzeichner und Verifizierer halten sich an die PK_SignatureScheme-Schnittstelle. Unterzeichner implementieren weiter PK_Signer, während Verifier PK_Verifier weiter implementieren.

Die Crypto ++ RSA Objekte würden wie so aussehen:

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

Die Crypto ++ Rabin-Williams Objekte aussehen würde so:

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

Die Crypto ++ Rabin Objekte wie so aussehen würde,

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

Die Objekte sind konsistent und Sie können sie ein- und auslagern.

Übrigens sollten Sie in Rabin-Williams schauen, um zu sehen, ob es Ihren Bedürfnissen entspricht. Siehe auch Bernsteins RSA signatures and Rabin–Williams signatures: the state of the art.


ich CryptoPP bin mit dem Code für die Codierung funktioniert ...

Schrott es. Der Exponent, den Sie verwenden, ist gut bekannt, daher gibt es keine echte Sicherheit in dem, was Sie tun. Es gibt Möglichkeiten, die Sicherheit zu verbessern, aber es klingt wie Sie eine PSSR stattdessen möchten.

Hier sind die zwei Beispiel aus dem Wiki RSA PSSR mit:

Und hier ist der Code-Unterzeichner für RSA Probabilistic Signature Scheme with Recovery mit einigen Ihrer Sachen Eingeschaltet. Beachten Sie, dass Sie eine echte RandomNumberGenerator benötigen, da die Signatur zufällig ist.

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

Und hier ist der Verifizierer Code für RSA Probabilistic Signature Scheme with Recovery mit einigen Ihrer Sachen eingewählt. Beachten Sie, dass Sie nicht RandomNumberGenerator brauchen, so dass Sie irgendwo seine NullRNG() bei Bedarf nutzen können.

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

... aber der Entschlüsselungscode löst eine Ausnahme: "Klasse CryptoPP :: InvertibleRSAFunction: Fehlende erforderlichen Parameter 'prime1'"

Yep, encrypt mit dem privaten Schlüssel ist nicht eine gültige kryptografische Transformation. Ich bin mir ziemlich sicher, dass entschlüsseln mit dem öffentlichen Schlüsselnicht gültig ist, entweder :)


Ich bin nicht, da ich Sie nicht glauben, gehen Sie den Code für die Verschlüsselung und Entschlüsselung zu schaffen brauchen. Aber Sie können es unter RSA Encryption Schemes auf dem Crypto ++ Wiki finden.

+0

SignatureWithRecovery funktioniert, aber es kann keine Nachricht verarbeiten, die größer als 128 Byte ist. Die Aufteilung der langen Nachricht in viele 128-Byte-Blöcke scheint keine gute Idee zu sein. Jetzt benutze ich 'a_exp_b_mod_c (message, d, n)', um die Kodierung selbst zu machen. – aj3423

+0

@ aj3423 - Nur so gibt es keine Überraschungen ... Ihre Nachricht ist immer noch zu groß. 'a_exp_b_mod_c' schneidet es still ab. Wenn Sie die umgekehrte Umwandlung ausführen, erhalten Sie eine abgeschnittene Nachricht zurück. Sehen Sie sich [Raw RSA] (http://www.cryptop.com/wiki/Raw_RSA) an und untersuchen Sie die Nachricht, die Sie wiederherstellen (der relevante Abschnitt ist [Private Schlüsselverschlüsselung] (http://www.cryptop.com/wiki)/Raw_RSA # Private_Key_Encryption)). Um das Abschneiden zu vermeiden: Ist es möglich, die Größe des Moduls zu erhöhen oder eine kleinere Nachricht zu verwenden? – jww

+0

@ aj3423 - Achte auch darauf, dass du * wirklich * auf die Randomisierung der Signatur verzichten willst. Das zitierte Bernstein-Papier spricht darüber, warum Sie in Abschnitt 5 eine Signatur per Randomisieren wollen. Die Angriffe auf nicht-randomisierte Signaturen gibt es seit 1979. – jww

0

Sie möchten also eine Nachricht mit Ihrem privaten Schlüssel signieren? Dieser Link hat ein Beispiel, vielleicht hilft es (Code und Link unten). Beachten Sie auch, dass nicht alle Signaturen verschlüsselt sind. Zum Beispiel verwendet ECDSA, das von Bitcoin verwendet wird, eine Signaturoperation, die eine Zufallszahl als eine Eingabe verwendet, wobei beim Signieren keine Verschlüsselung erfolgt.

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, aber es scheint mir, was er tun möchte, ist die klassische compute-hash-of-msg-> verschlüsseln - Hash-mit-privat-Schlüssel. Dann kann der Empfänger die Authentizität von msg überprüfen, indem er den öffentlichen Schlüssel sender: s verwendet, wenn dieser Schlüssel CA-verifiziert und vertrauenswürdig ist. –