openssl - Convertir la clave de pem en formato ssh-rsa
openssh (7)
El siguiente script obtendría el certificado de clave pública ci.jenkins-ci.org en formato DER codificado en base64 y lo convertiría en un archivo de clave pública de OpenSSH. Este código supone que se utiliza una clave RSA de 2048 bits y saca mucho de la answer Ian Boyd. He explicado un poco más cómo funciona en los comentarios de este artículo en la wiki de Jenkins.
echo -n "ssh-rsa " > jenkins.pub
curl -sfI https://ci.jenkins-ci.org/ | grep X-Instance-Identity | tr -d //r | cut -d/ -f2 | base64 -d | dd bs=1 skip=32 count=257 status=none | xxd -p -c257 | sed s/^/00000007/ 7373682d727361/ 00000003/ 010001/ 00000101/ / | xxd -p -r | base64 -w0 >> jenkins.pub
echo >> jenkins.pub
Tengo un certificado en formato der
, de él con este comando genero una clave pública:
openssl x509 -inform der -in ejbcacert.cer -noout -pubkey > pub1key.pub
Lo que resulta en esto:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vbqajDw4o6gJy8UtmIbkcpnk
O3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2
eHnHl5CB8ruRX9fBl/KgwCVr2JaEuUm66bBQeP5XeBotdR4cvX38uPYivCDdPjJ1
QWPdspTBKcxeFbccDwIDAQAB
-----END PUBLIC KEY-----
¿Cómo puedo obtener una clave pública como esta? ¿Desde el certificado o desde esta clave pública?
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC7vbqajDw4o6gJy8UtmIbkcpnkO3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2eHnHl5CB8ruRX9fBl/KgwCVr2JaEuUm66bBQeP5XeBotdR4cvX38uPYivCDdPjJ1QWPdspTBKcxeFbccDw==
Esto fue obtenido con este comando:
ssh-keygen -y -f private_key1.pem > public_key1.pub
No es necesario compilar cosas. Puedes hacer lo mismo con ssh-keygen
:
ssh-keygen -f pub1key.pub -i
leerá la clave pública en formato openssl desde pub1key.pub
y la pub1key.pub
en formato OpenSSH.
Nota : en algunos casos, deberá especificar el formato de entrada:
ssh-keygen -f pub1key.pub -i -mPKCS8
De los documentos ssh-keygen (From man ssh-keygen):
-m formato_clave Especifique un formato de clave para las opciones de conversión -i (importación) o -e (exportación). Los formatos de clave admitidos son: "RFC4716" (clave pública o privada RFC 4716 / SSH2), "PKCS8" (clave pública PEM PKCS8) o "PEM" (clave pública PEM). El formato de conversión predeterminado es "RFC4716".
No hay necesidad de guiones u otros ''trucos'': openssl
y ssh-keygen
son suficientes. Supongo que no hay contraseña para las claves (lo cual es malo).
Genera un par RSA
Todos los métodos siguientes dan un par de claves RSA en el mismo formato
Con openssl ( hombre genrsa )
openssl genrsa -out dummy-genrsa.pem 2048
En OpenSSL v1.0.1
genrsa
es reemplazada porgenpkey
por lo que esta es la nueva forma de hacerlo ( man genpkey ):openssl genpkey -algorithm RSA -out dummy-genpkey.pem -pkeyopt rsa_keygen_bits:2048
Con ssh-keygen
ssh-keygen -t rsa -b 2048 -f dummy-ssh-keygen.pem -N '''' -C "Test Key"
Conversión de DER a PEM
Si tiene un par de claves RSA en formato DER, puede convertirlo a PEM para permitir la conversión de formato a continuación:
Generacion:
openssl genpkey -algorithm RSA -out genpkey-dummy.cer -outform DER -pkeyopt rsa_keygen_bits:2048
Conversión:
openssl rsa -inform DER -outform PEM -in genpkey-dummy.cer -out dummy-der2pem.pem
Extraiga la clave pública del par RSA con formato PEM
en formato PEM:
openssl rsa -in dummy-xxx.pem -pubout
en formato OpenSSH v2 see :
ssh-keygen -y -f dummy-xxx.pem
Notas
Sistema operativo y versión de software:
[user@test1 ~]# cat /etc/redhat-release ; uname -a ; openssl version
CentOS release 6.5 (Final)
Linux test1.example.local 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
OpenSSL 1.0.1e-fips 11 Feb 2013
Referencias
Para responder a mi propia pregunta, después de publicar en la lista de correo de openssl obtuve esto:
Aquí está el código C para convertir de una clave pública de OpenSSL a una clave pública de OpenSSH. Puede tomar el código de este enlace y compilarlo usted mismo:
static unsigned char pSshHeader[11] = { 0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61};
static int SshEncodeBuffer(unsigned char *pEncoding, int bufferLen, unsigned char* pBuffer)
{
int adjustedLen = bufferLen, index;
if (*pBuffer & 0x80)
{
adjustedLen++;
pEncoding[4] = 0;
index = 5;
}
else
{
index = 4;
}
pEncoding[0] = (unsigned char) (adjustedLen >> 24);
pEncoding[1] = (unsigned char) (adjustedLen >> 16);
pEncoding[2] = (unsigned char) (adjustedLen >> 8);
pEncoding[3] = (unsigned char) (adjustedLen );
memcpy(&pEncoding[index], pBuffer, bufferLen);
return index + bufferLen;
}
int main(int argc, char** argv)
{
int iRet = 0;
int nLen = 0, eLen = 0;
int encodingLength = 0;
int index = 0;
unsigned char *nBytes = NULL, *eBytes = NULL;
unsigned char* pEncoding = NULL;
FILE* pFile = NULL;
EVP_PKEY *pPubKey = NULL;
RSA* pRsa = NULL;
BIO *bio, *b64;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
if (argc != 3)
{
printf("usage: %s public_key_file_name ssh_key_description/n", argv[0]);
iRet = 1;
goto error;
}
pFile = fopen(argv[1], "rt");
if (!pFile)
{
printf("Failed to open the given file/n");
iRet = 2;
goto error;
}
pPubKey = PEM_read_PUBKEY(pFile, NULL, NULL, NULL);
if (!pPubKey)
{
printf("Unable to decode public key from the given file: %s/n", ERR_error_string(ERR_get_error(), NULL));
iRet = 3;
goto error;
}
if (EVP_PKEY_type(pPubKey->type) != EVP_PKEY_RSA)
{
printf("Only RSA public keys are currently supported/n");
iRet = 4;
goto error;
}
pRsa = EVP_PKEY_get1_RSA(pPubKey);
if (!pRsa)
{
printf("Failed to get RSA public key : %s/n", ERR_error_string(ERR_get_error(), NULL));
iRet = 5;
goto error;
}
// reading the modulus
nLen = BN_num_bytes(pRsa->n);
nBytes = (unsigned char*) malloc(nLen);
BN_bn2bin(pRsa->n, nBytes);
// reading the public exponent
eLen = BN_num_bytes(pRsa->e);
eBytes = (unsigned char*) malloc(eLen);
BN_bn2bin(pRsa->e, eBytes);
encodingLength = 11 + 4 + eLen + 4 + nLen;
// correct depending on the MSB of e and N
if (eBytes[0] & 0x80)
encodingLength++;
if (nBytes[0] & 0x80)
encodingLength++;
pEncoding = (unsigned char*) malloc(encodingLength);
memcpy(pEncoding, pSshHeader, 11);
index = SshEncodeBuffer(&pEncoding[11], eLen, eBytes);
index = SshEncodeBuffer(&pEncoding[11 + index], nLen, nBytes);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bio = BIO_new_fp(stdout, BIO_NOCLOSE);
BIO_printf(bio, "ssh-rsa ");
bio = BIO_push(b64, bio);
BIO_write(bio, pEncoding, encodingLength);
BIO_flush(bio);
bio = BIO_pop(b64);
BIO_printf(bio, " %s/n", argv[2]);
BIO_flush(bio);
BIO_free_all(bio);
BIO_free(b64);
error:
if (pFile)
fclose(pFile);
if (pRsa)
RSA_free(pRsa);
if (pPubKey)
EVP_PKEY_free(pPubKey);
if (nBytes)
free(nBytes);
if (eBytes)
free(eBytes);
if (pEncoding)
free(pEncoding);
EVP_cleanup();
ERR_free_strings();
return iRet;
}
Todas las respuestas incorrectas. Este es el correcto:
ssh-keygen -i -m PKCS8 -f public-key.pem
ssh-keygen -f private.pem -y > public.pub