Не могу DER кодировать и BER декодировать открытый ключ RSA
У меня проблемы с использованием Crypto++ для сохранения открытого ключа RSA (что я получил загрузку файла закрытого ключа в формате PKCS#8). При декодировании ключа я всегда получаю BERDecodeErr
исключение.
Вот код, который я использую:
CryptoPP::RSASSA_PKCS1v15_SHA_Signer _signer;
CryptoPP::RSASSA_PKCS1v15_SHA_Verifier _verifier;
CryptoPP::ByteQueue bytes;
//_signer.AccessPublicKey().Save(bytes); // seem to save private key instead
_signer.AccessKey().DEREncodePublicKey(bytes);
//_verifier.AccessKey().Load(bytes);
//_verifier.AccessKey().BERDecodePublicKey(bytes, 0, 0);
_verifier.AccessPublicKey().Load(bytes);
Я также попытался с инструкциями, приведенными выше, но безуспешно.
Как вы делаете, чтобы сохранить или открыть открытый ключ?
Открытый ключ выглядит в шестнадцатеричном формате, есть ли инструмент для проверки его формата / действительности (относительно того, что поддерживает crypto++)?
3081890281810097e24f2e95504a397e90fbc56d1b330ab2ab97a0d326007b890e40013f9e1d9bd9
f54b0c0840782ddae19b5b4595d8f8b9ffe0d2120174fcbc39585c5867cd2dfba69f8e540caa2c52
de8f08278a34e9249120500117f0ba756c5bb2be660013160db9f82f75deb7ccf63742a9e945da6c
cf30c2b109b73342daaabd02b872e50203010001
1 ответ
Я не уверен, что полностью понимаю вашу проблему. Но вы выглядите так, как будто вы на правильном пути, используя либо Load
/Save
или же BERDecodePublicKey
/DEREncodePublicKey
,
Вот как я бы подошел к этому, если бы у вас был закрытый ключ в кодировке PKCS#8.
FileSource privateKey("<private key>", true);
RSASSA_PKCS1v15_SHA_Signer signer;
signer.AccessKey().Load(privateKey);
AutoSeededRandomPool prng;
bool valid = signer.AccessKey().Validate(prng, 3);
...
RSASSA_PKCS1v15_SHA_Verifier verifier(signer);
FileSink publicKey("<public key>", true);
verifier.AccessKey().Save(publicKey);
Затем вы можете использовать Гутманнаdumpasn1
распечатать это:
$ dumpasn1 <public key>
...
Я считаю, что вы также можете преобразовать закрытый ключ / подписавшего в открытый ключ / верификатор с помощью:
RSASSA_PKCS1v15_SHA_Signer signer;
signer.AccessKey().Load(privateKey);
RSASSA_PKCS1v15_SHA_Verifier verifier;
signer.MakePublic(verifier);
Есть также страница в вики Crypto++, которая более подробно об этом говорит: ключи и форматы. И есть страница, посвященная кодированию PEM, если интересно: PEM Pack. Если вам нужна кодировка PEM, вы должны сами скомпилировать библиотеку.
Вот код, который я использовал с открытым ключом, который вы опубликовали. У него не было проблем.
string key = "3081890281810097e24f2e95504a397e90fbc56d1b330ab2ab97a0d326007b890e40013f9e1d9bd9 \
f54b0c0840782ddae19b5b4595d8f8b9ffe0d2120174fcbc39585c5867cd2dfba69f8e540caa2c52 \
de8f08278a34e9249120500117f0ba756c5bb2be660013160db9f82f75deb7ccf63742a9e945da6c \
cf30c2b109b73342daaabd02b872e50203010001";
ByteQueue queue;
StringSource ss(key, true, new HexDecoder(new Redirector(queue)));
RSASSA_PKCS1v15_SHA_Verifier verifier;
verifier.AccessKey().BERDecodePublicKey(queue, false, 0);
AutoSeededRandomPool prng;
bool result = verifier.AccessKey().Validate(prng, 3);
if(!result)
throw Exception(Exception::OTHER_ERROR, "Failed to validate public key");
Если вы устанавливаете PEM Pack, вы можете добавить следующее:
FileSink sink("public-key.pem", true);
PEM_Save(sink, verifier.GetKey());
Это даст вам:
$ cat public-key.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCX4k8ulVBKOX6Q+8VtGzMKsquX
oNMmAHuJDkABP54dm9n1SwwIQHgt2uGbW0WV2Pi5/+DSEgF0/Lw5WFxYZ80t+6af
jlQMqixS3o8IJ4o06SSRIFABF/C6dWxbsr5mABMWDbn4L3Xet8z2N0Kp6UXabM8w
wrEJtzNC2qq9Arhy5QIDAQAB
-----END PUBLIC KEY-----
А также:
$ openssl rsa -in public-key.pem -pubin -text -noout
Public-Key: (1024 bit)
Modulus:
00:97:e2:4f:2e:95:50:4a:39:7e:90:fb:c5:6d:1b:
33:0a:b2:ab:97:a0:d3:26:00:7b:89:0e:40:01:3f:
9e:1d:9b:d9:f5:4b:0c:08:40:78:2d:da:e1:9b:5b:
45:95:d8:f8:b9:ff:e0:d2:12:01:74:fc:bc:39:58:
5c:58:67:cd:2d:fb:a6:9f:8e:54:0c:aa:2c:52:de:
8f:08:27:8a:34:e9:24:91:20:50:01:17:f0:ba:75:
6c:5b:b2:be:66:00:13:16:0d:b9:f8:2f:75:de:b7:
cc:f6:37:42:a9:e9:45:da:6c:cf:30:c2:b1:09:b7:
33:42:da:aa:bd:02:b8:72:e5
Exponent: 65537 (0x10001)
Наконец, разница между:
verifier.AccessKey()
: получаетRSA::Public
ключ, ключ не постоянныйverifier.GetKey()
: получаетRSA::Public
ключ, ключ постоянный