Mogą to być interesujące strony Crypto++ Keys and Formats i Crypto++ RSA Cryptography.
Jeśli generowanie parametrów RSA tak:
AutoSeededRandomPool rng;
InvertibleRSAFunction params;
params.GenerateRandomWithKeySize(rng, 2048);
Można użyć użyć DEREncode
i BERDecode
metod InvertibleRSAFunction
kodować i dekodować wszystkie parametry odpowiednio:
{
FileSink output("rsaparams.dat");
params.DEREncode(output);
}
InvertibleRSAFunction params2;
{
FileSource input("rsaparams.dat", true);
params2.BERDecode(input);
}
Aby kodować/dekodować osobno i publicznie materiał oddzielnie, użyj metod DEREncode
i BERDecode
na RSA::PrivateKey
isamiobiektów:
// 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
i FileSink
to tylko przykład źródło i zatopić obiektów można użyć. Procedury kodowania/dekodowania pobierają obiekty BufferedTransformation
jako parametry, dzięki czemu można użyć dowolnych innych odpowiednich implementacji tego interfejsu.
Na przykład ArraySink
może być używany do zapisywania danych w buforze pamięci, który można dostarczyć, a do odczytu z bufora można użyć StringSource
(also aliased as ArraySource
).
Oto niektóre kodu pokazujący wykorzystanie ArraySink
i ArraySource
na obie strony materiału klucza prywatnego przez 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);
(Patrz także @jww's answer na przykład z pominięciem bufora o stałym rozmiarze za pomocą ByteQueue
).
Kolejny przykład użycia std::string
do przechowywania materiału klucza i użycia do napisania klasy StringSink
, co pozwala uniknąć zarządzania buforami (ciąg zmienia rozmiar automatycznie, aby dopasować ilość zakodowanych danych). Zauważ, że jest to nadal dane binarne, mimo że są w obiekcie 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);
Ewentualnie, jeśli chcesz kontrolować formacie siebie, można użyć metod obiektu InvertibleRSAFunction
lub klawisz obiektów wyodrębnić poszczególne parametry (jak pokazano w „Crypto ++ RSA Cryptography” link powyżej) i używać, aby wyodrębnić wartości dla przechowywania w swoim własnym formacie:
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();
mogłyby one być następnie przywrócony do nowego InvertibleRSAFunction
lub RSA::*Key
przykład podczas odczytu z pliku lub kontenera, przy użyciu odpowiednich metod ustawiających (SetModulus()
, SetPrime1()
itp.).
Właściwie , Zastanawiam się teraz, czy problem polegał na wybraniu odpowiedniego źródła/zlewu (np. 'ArraySink' /' ArraySource' w innym miejscu niż 'FileSource' /' FileSink'), a nie na kodowaniu/dekodowaniu kluczowego materiału takiego jak ja odpowiedział. Możesz wyjaśnić? – softwariness
@swarowność Twoja odpowiedź jest naprawdę dobra, ale tak, to raczej wybór odpowiedniego źródła/zlewu: D Nie wiedziałem o ArraySink przez O.o, które mogłoby pomóc. Jeśli umieścisz w odpowiedzi coś na temat zlewów, to zaakceptuję to. – deW1
Odpowiedź teraz zaktualizowana z przykładem pokazującym materiał z kluczem w obie strony za pomocą bufora pamięci, a druga z kluczowym materiałem przechowywanym w std :: string z StringSink/StringSource, który omija niektóre z zarządzania buforami. – softwariness