2009-11-02 25 views
7

Estoy tratando de implementar el cifrado RSA tanto en Java como en PHP, pero parece que no logro que PHP reconozca mis claves públicas/privadas de Java. Aquí está el código Java para envío/recepción del público y las claves privadas:Cifrado RSA: Java a PHP

public static byte[] EncodePublicKey(PublicKey _publickey) throws Exception 
{ 
    return _publickey.getEncoded(); 
} 

public static PublicKey DecodePublicKey(byte[] _encodedkey) throws Exception 
{ 
    KeyFactory fac = KeyFactory.getInstance("RSA"); 
    X509EncodedKeySpec encodedKey = new X509EncodedKeySpec(_encodedkey); 
    return fac.generatePublic(encodedKey); 
} 

public static byte[] EncodePrivateKey(PrivateKey _privatekey) throws Exception 
{ 
    return _privatekey.getEncoded(); 
} 

public static PrivateKey DecodePrivateKey(byte[] _encodedkey) throws Exception 
{ 
    KeyFactory fac = KeyFactory.getInstance("RSA"); 
    PKCS8EncodedKeySpec encodedKey = new PKCS8EncodedKeySpec(_encodedkey); 
    return fac.generatePrivate(encodedKey); 
} 

primera vez que trató de utilizar las funciones PERA Crypt_RSA, pero no es compatible con X.509 o PKCS8 (que simplemente codifica la base 64 serializado módulo, exponente y tipo de clave). Luego probé la función OpenSSL "openssl_get_publickey" pero tampoco parece reconocer el formato.

Cualquier ayuda sería muy apreciada O.o

Respuesta

10

es necesario convertir el formato binario (DER) de Java a PEM de OpenSSL (y los enlaces de PHP). Puede probar sus archivos de clave Java usando la línea de comando OpenSSL especificando la opción -inform DER en la línea de comando.

<? 
function pem2der($pem_data) { 
    $begin = "KEY-----"; 
    $end = "-----END"; 
    $pem_data = substr($pem_data, strpos($pem_data, $begin)+strlen($begin)); 
    $pem_data = substr($pem_data, 0, strpos($pem_data, $end)); 
    $der = base64_decode($pem_data); 
    return $der; 
} 

function der2pem($der_data) { 
    $pem = chunk_split(base64_encode($der_data), 64, "\n"); 
    $pem = "-----BEGIN PUBLIC KEY-----\n".$pem."-----END PUBLIC KEY-----\n"; 
    return $pem; 
} 

// load the public key from a DER-encoded file 
$pubkey = der2pem(file_get_contents("pubkey")); 
?> 

Para obtener más información sobre el uso de las teclas de OpenSSL en Java, check out this link.

+0

¿Cómo podría entonces convertir la codificación ASN.1 al formato PEM en PHP? – user201117

+0

Actualicé mi respuesta después de encontrar el enlace de arriba ... – jheddings

+0

¡Esto funcionó! Gracias =) – user201117

5

Las funciones de PHP requieren claves codificadas PEM. Es trivial convertir claves codificadas DER en PEM.

Aquí está mi código para convertir PKCS # 8 clave privada a PEM,

function pkcs8_to_pem($der) { 

    static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----"; 
    static $END_MARKER = "-----END PRIVATE KEY-----"; 

    $value = base64_encode($der); 

    $pem = $BEGIN_MARKER . "\n"; 
    $pem .= chunk_split($value, 64, "\n"); 
    $pem .= $END_MARKER . "\n"; 

    return $pem; 
} 

Para clave pública en X509, reemplace privado con PÚBLICO en los marcadores.

+0

Esto hace lo mismo que la respuesta aceptada, pero vino después. – user201117

1

http://code.google.com/p/simplersalibrary/ es una herramienta simple, si quiere encriptar algo en Java y descifrar en PHP o encriptar en java y descifrar en PHP, simplersa también puede generar los archivos de pem para PHP.

1

También puede tratar de utilizar CastleCrypt, lo que permite un fácil utilizar el cifrado RSA en Java y PHP: https://github.com/wessnerj/CastleCrypt

Para la generación de claves es posible que desee probar con openssl:

openssl genrsa -out privateKey.pem 2048 
openssl pkcs8 -topk8 -nocrypt -in privateKey.pem -outform der -out privateKey.der 
openssl rsa -in privateKey.pem -pubout -outform PEM -out publicKey.pem 
openssl rsa -in privateKey.pem -pubout -outform DER -out publicKey.der 

Este comando le da claves privadas y públicas tanto en formato DER como en formato PEM. Para JAVA debes usar las teclas .der y para PHP las teclas .pem.