Intercambio de claves utilizando PKI

3

Soy nuevo en el campo de la criptografía y estoy probando un programa de muestra para comprender el mecanismo de intercambio de claves PKI. Intenté crear un certificado autofirmado utilizando openssl

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.cer

Esto me dio un archivo de certificado que puedo publicar en mi programa cliente y un archivo de clave privada que yo usuario para descifrar el texto cifrado por los programas cliente. Puedo cifrar texto sin formato utilizando el archivo de certificado, pero tengo problemas para obtener la clave privada. ¿Cómo leo la clave privada del archivo de clave para usarla en el descifrado?

Mi entendimiento con el intercambio de claves es que tengo una clave pública y privada autofirmada u obtenida de CA; publicar la clave pública a las aplicaciones (remitente) que pretenden enviarme un mensaje. El remitente encripta una clave simétrica con la clave pública publicada y el receptor desencripta el mensaje usando la clave privada y, por lo tanto, ambas partes han intercambiado la clave simétrica por una criptografía bidireccional adicional.

Mientras trato de extraer la clave privada usando el siguiente código java

public class RSAToy {


    private static final String BEGIN_RSA_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n"
            + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDW6ofjl8o8sjGg\n"
            + "ANqLneMcrq+xUYVRnKT1mGtboMYHJqtgNIbCzMo4Ym4Uw5+m1JEa2fxbcExp1JAK\n"
            + "A3Cmih+KaJ/gjyaJDKHrTuRN7hs4oSo6aPTIAW3euuqWH7xrFOIvXRRIqRWu4oir\n"
            + "xEjjyQ2IxqkPssf+AUAkz9DiH6phGIaXHXocIsCSEssZWkYd7WZ0HYL3Bfz+W4aY\n"
            + "+PfKDwflMLknsWOkmzc8N+i4Bac3IxOuFhwmg3y2YQq//ZkkaJv3OVIjj6v2OuRY\n"
            + "vgfrPs9dwkshloxp8HRDlA5upXiBiv3JOawbkBUs+bmxzjTNT+vyliKb4qq9ZCAF\n"
            + "ikV5BKazAgMBAAECggEADao137O8CSXvX9QOEUiFs0IsK6MaTfkex/rcAKR1UukT\n"
            + "hndwhhxNU052310c3pevbjyj/hBi22vHiMt1MzGfFcbXO4j+k0I5XWPTwly8YFpm\n"
            + "+/XGcp0cpkfOOKNl8I0QYKCTdJdDqK4AsKM3WzxiXur6vuPIMY9Uy8Jm7qnCxI+T\n"
            + "xoYW857hX9caDvDS+YyMzHFHfcuqI0//4AzjgxgIqy8D0w9u4Xr61mAsLYNsXAUt\n"
            + "ZPOXoI8KhQ7DAAYzmY3OnBRr3fQbM2yXVxdW9Tv6bhmFrpuicUHfMRJrnjzK1b4O\n"
            + "nPtn5542rVzCXe6FWu1c98Gw0S+oo3G8gfgg/IpukQKBgQD4cnXrMGV2ETE3rWjD\n"
            + "drEo0pGJ8UCAwl08xBRY5dlK6SkfsnMOiZhQIsFLqMvknEmYNarWdu4Bmu3lgoo1\n"
            + "/JO0UGUifbklhDTQoy7q12jzCLMMQMSm5ziTCehJ2lOMI+Z+gD+AQD9ltCUBCQrR\n"
            + "s8YhAR8TH5aDtb2kkohRrDufKwKBgQDdcx2LvnjaR1lB9MQ85snTx2LQt26ewyRd\n"
            + "2zxBBQtNGQvmP0mj3t/88tHu+MPQCCvHpFiPdcs7VN/SEfE6vw9R0YY6b/YIKelm\n"
            + "uj9t5Ar2EZtUvbiVCYyKXAl5tgXNAESTP8LDidhQ41UjJS0ZaVwXbCwDVDZqS4NY\n"
            + "JGSeq9SSmQKBgQCGQ40YOcJLKQVZGnyoTUd2UT1Xt6ntK5ypjymT1Ts1sYWI3K4z\n"
            + "KAbJH88oLSNq+08GU9JsLj93XJu90WsRu9qyslPFbP4WmTjVm6pqPVk5JfVk5Meh\n"
            + "jwlS5SLEbpmB/ZC9wl8O1ymrs8vfoFxZcXbcNTfu5L45lYjUHGBRCuv5mwKBgBN6\n"
            + "AGs+AVsRU2RdprTEh5O8wZAh0fTcrOIkWhRN4USSo11Iy61B+OlCYfxmnLI7Rb51\n"
            + "UeSsM4ewW08ajODh1PMZPnj9R+JH7WM/ljyQBfbGbabyWL2i7V1t4td1juUM1Psu\n"
            + "bG7OPNxAYkiJCIJnpdXZibVxPqfypEaoTME306ZhAoGBAO9E1RbKR+9p/h7xzXPE\n"
            + "0vFyN0ItW2Mu3ESE4VRplYx4ht/zZ4gBJMHLNNQCk3IQGflizJ6+On74z6RnYxAy\n"
            + "jiF9zLqj8NKy24wrWithYepG4C0JL6xg2k3gYLxyuccXak06D0ABDxnwJcXrZvmq\n"
            + "zuhsR8X+g3gxaGr7dTgMcZ2J\n"
            + "-----END PRIVATE KEY-----";


    public static void main(String[] args) throws Exception {

        // Remove the first and last lines

        String privKeyPEM = BEGIN_RSA_PRIVATE_KEY.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
        privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");
//        System.out.println(privKeyPEM);

        // Base64 decode the data

        byte [] encoded = Base64.decodeBase64(privKeyPEM);

        // PKCS8 decode the encoded RSA private key

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

//        RSAPrivateKeySpec keySpec = new R
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey privKey = kf.generatePrivate(keySpec);

        // Display the results

        System.out.println(privKey);
    }
}

Me estoy haciendo

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=111, too big.
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)

¿Cómo puedo solucionarlo y extraer la clave privada para descifrar mi mensaje codificado? Cualquier ayuda es muy apreciada.

    
pregunta Vijay Selvaraj 07.11.2012 - 09:34
fuente

3 respuestas

3

Cuando OpenSSL crea una clave privada, utiliza su propio formato; en realidad, el formato bruto basado en ASN.1 que se describe en PKCS # 1 . Esto no es PKCS # 8 , que es un wrapper alrededor de eso formato.

Puede convertir la clave privada al formato PKCS # 8 de esta manera:

openssl pkcs8 -in privateKey.key -topk8 -nocrypt -out privateKey.pk8

La opción "-nocrypt" se debe a que PKCS # 8 opcionalmente admite el cifrado basado en contraseña de la clave privada. Puedes agregar -outform DER para evitar la codificación PEM ("PEM" es Base64 más un par de encabezados, que eliminas en tu código).

    
respondido por el Thomas Pornin 07.11.2012 - 13:09
fuente
0

Estás creando un certificado x509, pero luego intentas importar una clave de formato PKCS8. La clave exportada no es compatible. Debe exportar un PKCS8 DER / PEM (dependiendo de lo que quiera Java) o cambiar su código para importar claves x509.

    
respondido por el Polynomial 07.11.2012 - 11:13
fuente
0

Si también desea analizar en Windows, debería utilizar

keyStr.replaceAll("(-+BEGIN RSA PRIVATE KEY-+\r?\n|-+END RSA PRIVATE KEY-+\r?\n?)", "");

para sustituir la cadena DER.

    
respondido por el Rik 03.02.2016 - 17:49
fuente

Lea otras preguntas en las etiquetas