Я использую C ++ с библиотеками nss и nspr в 64-битной Ubuntu Linux и пытаюсь конвертировать CERTCertificate derCert в SECKEYPublicKey, но SECKEY_ImportDERPublicKey продолжает возвращать -8183:
Библиотека безопасности: неправильно отформатированное DER-кодированное сообщение.
Я также пытался использовать SECKEY_ImportDERPublicKey с CERTCertificate derPublicKey, но получил тот же ответ.
Какая пара функций должна использоваться для derCert, а какая для преобразования derPublicKey в SECItem и обратно в SECKEYPublicKey или CERTCertificate?
Чтобы ответить на мой собственный вопрос …
CERTCertificate содержит две переменные-члена derCert и derPublicKey (оба типа SECItem), которые меня интересовали.
Чтобы получить открытый ключ, вы можете сохранить значение CERTCertificate derPublicKey или получить то же значение из SECKEYPublicKey:
// cert is of type CERTCertificate
SECKEYPublicKey* publicKey = CERT_ExtractPublicKey( cert );
SECItem* derPublicKey = SECKEY_EncodeDERSubjectPublicKeyInfo( publicKey );
// put the key into string
std::string keyString( (char*)derPublicKey->data, derPublicKey->len );
Для декодирования открытого ключа из строки вы используете:
SECItem derKeyItem = {
.type = siBuffer,
.data = (unsigned char*)keyString.c_str(),
.len = (unsigned int)keyString.size()
};
CERTSubjectPublicKeyInfo* pubInf = SECKEY_DecodeDERSubjectPublicKeyInfo( &derKeyItem );
SECKEYPublicKey* publicKey = SECKEY_ExtractPublicKey( pubInf );
Для сохранения сертификата вы сохраняете derCert.
Чтобы загрузить сертификат и получить открытый ключ:
SECItem derCertItem = {
.type = siBuffer,
.data = (unsigned char*)certStr.c_str(),
.len = (unsigned int)certStr.size()
};
CERTCertificate cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCertItem, nullptr, false, false);
SECKEYPublicKey* publicKey = CERT_ExtractPublicKey(cert);
Приведенный выше код является примером кода. Для производственного кода следует использовать интеллектуальные указатели (уникальные / общие), а их деструкторы должны вызывать соответствующие функции nss destroy.