Le pagine Crypto++ Keys and Formats e Crypto++ RSA Cryptography possono essere di interesse.
Se si sta generando i parametri di RSA in questo modo:
AutoSeededRandomPool rng;
InvertibleRSAFunction params;
params.GenerateRandomWithKeySize(rng, 2048);
È possibile utilizzare l'uso dei DEREncode
e BERDecode
metodi di InvertibleRSAFunction
per codificare e decodificare tutti i parametri, rispettivamente:
{
FileSink output("rsaparams.dat");
params.DEREncode(output);
}
InvertibleRSAFunction params2;
{
FileSource input("rsaparams.dat", true);
params2.BERDecode(input);
}
Per codificare/decodificare separatamente il materiale privato e pubblico, utilizzare i metodi DEREncode
e BERDecode
su RSA::PrivateKey
e RSA::PublicKey
oggetti stessi:
// Initialize keys from generated params
RSA::PrivateKey rsaPrivate(params);
RSA::PublicKey rsaPublic(params);
// Write keys to file
{
FileSink output("rsaprivate.dat");
rsaPrivate.DEREncode(output);
}
{
FileSink output("rsapublic.dat");
rsaPublic.DEREncode(output);
}
// Read keys from file into new objects
RSA::PrivateKey rsaPrivate2;
RSA::PublicKey rsaPublic2;
{
FileSource input("rsaprivate.dat", true);
rsaPrivate2.BERDecode(input);
}
{
FileSource input("rsapublic.dat", true);
rsaPublic2.BERDecode(input);
}
FileSource
e FileSink
sono solo sorgente di esempio e lavandino oggetti è possibile utilizzare. Le routine di codifica/decodifica prendono gli oggetti BufferedTransformation
come parametri, quindi è possibile utilizzare qualsiasi altra implementazione adatta di tale interfaccia.
Ad esempio, ArraySink
può essere utilizzato per scrivere dati in un buffer di memoria fornito dall'utente e StringSource
(also aliased as ArraySource
) può essere utilizzato per leggere da un buffer.
Ecco po 'di codice che mostra l'uso di ArraySink
e ArraySource
di andata e ritorno il materiale chiave privata attraverso una std::vector<byte>
:
RSA::PrivateKey rsaPrivate(params);
std::vector<byte> buffer(8192 /* buffer size */);
ArraySink arraySink(&buffer[0], buffer.size());
rsaPrivate.DEREncode(arraySink);
// Initialize variable with the encoded key material
// (excluding unwritten bytes at the end of our buffer object)
std::vector<byte> rsaPrivateMaterial(
&buffer[0],
&buffer[0] + arraySink.TotalPutLength());
RSA::PrivateKey rsaPrivate2;
ArraySource arraySource(
&rsaPrivateMaterial[0],
rsaPrivateMaterial.size(),
true);
rsaPrivate2.BERDecode(arraySource);
(Vedi anche @jww's answer per un esempio che evita il buffer di dimensioni fisse utilizzando una ByteQueue
).
E un altro esempio utilizza std::string
per archiviare il materiale della chiave e utilizzare la classe StringSink
per scrivere su questo, che evita parte della gestione del buffer (la stringa verrà ridimensionata automaticamente per corrispondere alla quantità di dati codificata). Si noti che questo è ancora dati binari anche se si trova in un oggetto std::string
.
RSA::PrivateKey rsaPrivate(params);
std::string rsaPrivateMaterial;
StringSink stringSink(rsaPrivateMaterial);
rsaPrivate.DEREncode(stringSink);
RSA::PrivateKey rsaPrivate2;
StringSource stringSource(rsaPrivateMaterial, true);
rsaPrivate2.BERDecode(stringSource);
In alternativa, se si desidera controllare il formato da soli, è possibile utilizzare i metodi dell'oggetto InvertibleRSAFunction
o gli oggetti chiave per estrarre i singoli parametri (come mostrato nel link "Crypto ++ RSA Cryptography" di cui sopra) e l'uso che per estrarre i valori per la conservazione nel proprio formato:
const Integer& n = params.GetModulus();
const Integer& p = params.GetPrime1();
const Integer& q = params.GetPrime2();
const Integer& d = params.GetPrivateExponent();
const Integer& e = params.GetPublicExponent();
Questi potrebbero poi essere ripristinati in un nuovo InvertibleRSAFunction
o RSA::*Key
esempio quando letta dal file o il contenitore, utilizzando i metodi setter corrispondenti (SetModulus()
, SetPrime1()
, eccetera.).
realtà , Mi chiedo ora se il problema fosse scegliere un source/sink adatto (es. 'ArraySink' /' ArraySource' invece di 'FileSource' /' FileSink'), non la codifica/decodifica del materiale chiave come ho risposta. Puoi chiarire? – softwariness
@softwariness la tua risposta è davvero buona, ma sì, si tratta di scegliere un source/sink adatto: D Non sapevo di ArraySink anche se O.o poteva essere d'aiuto. Se puoi includere qualcosa anche nei lavandini nella tua risposta, lo accetto. – deW1
Risposta ora aggiornata con un esempio che mostra il materiale della chiave round-tripping attraverso un buffer di memoria e un altro che mostra il materiale chiave memorizzato in una stringa std :: con StringSink/StringSource che evita parte della gestione del buffer. – softwariness