2012-03-22 30 views
12

Muchas veces, el usuario tendrá claves privadas RSA codificadas en PEM. Crypto ++ requiere que estas claves estén en formato DER para cargarlas. Me he estado preguntando a las personas para convertir sus archivos de forma manual PEM der antemano usando openssl así:Cargue la clave RSA privada codificada PEM en Crypto ++

openssl pkcs8 -in in_file.pem -out out_file.der -topk8 -nocrypt -outform der 

que funciona bien, pero algunas personas no entienden cómo hacer que ni ellos quieren. Entonces me gustaría convertir archivos PEM a archivos DER automáticamente dentro del programa.

Es tan simple como desglosar el "----- BEGIN CERTIFICATE -----" y "----- END CERTIFICATE -----" from the PEM o es alguna otra transformación requerida como ¿bien? Me dijeron que entre esos marcadores solo está codificado en b64 DER. Aquí hay algo de código que demuestra el problema:

// load the private key 
CryptoPP::RSA::PrivateKey PK; 
CryptoPP::ByteQueue bytes; 

try 
{ 
    CryptoPP::FileSource File(rsa.c_str(), true, new CryptoPP::Base64Decoder()); 
    File.TransferTo(bytes); 
    bytes.MessageEnd(); 

    // This line Causes BERDecodeError when a PEM encoded file is used 
    PK.Load(bytes); 
} 

catch (CryptoPP::BERDecodeErr) 
{ 
    // Convert PEM to DER and try to load the key again 
} 

me gustaría evitar llamadas al sistema para openssl decisiones y hacer la transformación en su totalidad en Crypto ++ para que los usuarios pueden proporcionar formato y las cosas "sólo trabajo". Gracias por cualquier consejo.

+0

¿Está buscando un decodificador en memoria, o también uno en disco? –

+0

@OrgnlDave - cualquier ejemplo usando Crypto ++ haría. – 01100110

+0

@ 01100110 - Crypto ++ ahora tiene este soporte como un complemento. Consulte [Paquete PEM] (http://www.cryptopp.com/wiki/PEM_Pack) en la wiki de Crypto ++. – jww

Respuesta

7

Sí, es una secuencia DER codificada con Base64. Sin embargo, tenga en cuenta que, además de mostrar los marcadores BEGIN y END, en el caso del formato de clave RSA, también debe quitar todos los indicadores que puedan insertarse entre el marcador BEGIN y los datos codificados. Solo la parte restante se puede decodificar con Base64 con éxito. Parece que alimenta el archivo de certificado completo al decodificador y necesita ser arreglado.

+0

Agradezco la respuesta. Puedo hacer la conversión con una llamada std :: system a openssl. Eso funciona bien, pero es un truco. Me gustaría hacer la conversión de PEM a DER por completo en Crypto ++. – 01100110

+0

Bienvenido a stackoverflow oLcount, +1 para esa respuesta. –

+0

No soy un experto en Crypto ++, pero parece que la biblioteca no admite la carga directa de certificados codificados PEM. Necesita agregar esa funcionalidad. Ya sea eliminando los marcadores de inicio/final usando std :: string directamente en su variable 'rsa', o escribiendo' CryptoPP :: BufferedTransformation' que hace el mismo trabajo. – orLcount

2

Sé que esta es una pregunta anterior, pero la de otros podría ser útil. Una vez que quites los marcadores, te queda el material de la clave "interna". De acuerdo con http://www.cryptopp.com/wiki/Keys_and_Formats#BER_and_DER_Encoding puede usar BERDecodePrivateKey para cargar esto. Por lo tanto, para cargar una clave openssl que ha tenido sus marcadores despojados puede hacer algo como

bool LoadKey(RandomNumberGenerator& rng, const std::string& file, 
    RSA::PrivateKey& key) 
{ 
    ByteQueue q; 
    FileSource KeyFile(file.c_str(), true, new Base64Decoder); 
    KeyFile.TransferTo(q); 
    key.BERDecodePrivateKey(q,false,0); // last 2 params unused 
    return key.Validate(rng, 2); 
} 
1

... Me gustaría convertir archivos PEM der archivos de forma automática dentro del programa.

En julio de 2014, se proporcionó un PEM Pack para la biblioteca Crypto ++. El paquete PEM es una implementación parcial del cifrado de mensajes que le permite leer y escribir claves codificadas PEM y parámetros, incluidas claves privadas cifradas. Los archivos adicionales incluyen soporte para RSA, DSA, EC, claves ECDSA y parámetros Diffie-Hellman.

Es un complemento de la biblioteca, y no parte de la biblioteca propiamente dicha. Descargue un archivo ZIP y agregue cinco archivos fuente a la biblioteca. Luego construyes la biblioteca (Crypto ++ los recoge automáticamente). El ZIP contiene cinco archivos fuente adicionales, un script para crear claves de prueba usando OpenSSL, un programa C++ para probar la lectura y escritura de las claves, y un script para verificar las claves escritas por Crypto ++ usando OpenSSL.

Así es como usted lo utilizaría:

CryptoPP::RSA::PrivateKey pk; 
CryptoPP::FileSource file("<rsa-key-file.pem>", true); 

CryptoPP::PEM_Load(file, pk); 

CryptoPP::AutoSeededRandomPool prng; 
bool = pk.Validate(prng, 3); 
if (! valid) 
    throw ... 

Si se cifran las claves, entonces aquí es cómo se cargarlo. El PEM Pack re-implementar de OpenSSL de EVP_BytesToKey, por lo que la obtención de claves que va a funcionar y se puede INTEROP:

CryptoPP::RSA::PrivateKey pk; 
CryptoPP::FileSource file("<rsa-key-file.pem>", true); 

std::string pass = "<super secret password>"; 
CryptoPP::PEM_Load(file, pk, pass.data(), pass.size()); 

CryptoPP::AutoSeededRandomPool prng; 
bool = pk.Validate(prng, 3); 
if (! valid) 
    throw ... 

También hay un PEM_Save, para que pueda escribir las claves directamente de Crypto ++.Por ejemplo:

// Generate it or load it from somewhere 
CryptoPP::RSA::PrivateKey pk = ...; 
CryptoPP::FileSink file("<rsa-key-file.pem>", true); 

CryptoPP::PEM_Save(file, pk); 

Y PEM_Save de una clave cifrada (o la tecla tiene la intención de cifrar):

// Generate it or load it from somewhere 
CryptoPP::RSA::PrivateKey pk = ...; 
CryptoPP::FileSink file("<rsa-key-file.pem>", true); 

std::string pass = "<super secret password>"; 
CryptoPP::PEM_Save(file, pk, "AES-128-CBC", pass.data(), pass.size()); 

PEM_Load hace no necesita un algoritmo debido a que su codificada en la cabecera encapsulada. PEM_Save necesita un algoritmo porque no hay un algoritmo predeterminado.

Cuestiones relacionadas