RSA Criptografia: Java para PHP
Pergunta
Estou tentando implementar a criptografia RSA em Java e PHP, mas não consigo fazer com que o PHP reconheça minhas chaves públicas/privadas Java. Aqui está o código Java para codificar/decodificar as chaves públicas e privadas:
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);
}
Eu tentei usar as funções Pear Crypt_RSA, mas ele não suporta X.509 ou PKCS8 (ele simplesmente baseia64 codifica o módulo, expoente e o tipo de chave serializados). Tentei então a função OpenSSL "OpenSSL_Get_PublicKey", mas também não parece reconhecer o formato.
Qualquer ajuda seria muito apreciada oo
Solução
Você precisa converter o formato binário (DER) de Java em PEM para OpenSSL (e as ligações PHP). Você pode testar seus arquivos de chave Java usando a linha de comando OpenSSL especificando o -inform DER
opção na linha 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 obter mais informações sobre o uso de teclas OpenSSL em Java, Confira este link.
Outras dicas
As funções PHP requerem teclas codificadas pelo PEM. É trivial converter teclas codificadas em PEM.
Aqui está o meu código para converter PKCS#8 Chave privada para 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 chave pública no x509, substitua privado pelo público em marcadores.
http://code.google.com/p/simplersalibrary/ é uma ferramenta simples, se você deseja criptografar algo em Java e descriptografar em PHP ou criptografar em Java e descriptografar no PHP, o Simplesa também pode gerar os arquivos PEM para PHP.
Você também pode tentar usar o CastleCrypt, que permite uma criptografia RSA fácil de usar em Java e PHP: https://github.com/wessnerj/castleCrypt
Para a geração de chaves, você pode querer experimentá -lo com o 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
Esses comandos fornecem a chave pública e privada no formato DER e PEM. Para Java, você deve usar as teclas .der e para PHP as teclas .PEM.