2011-01-07 31 views
9

Tengo una pequeña cadena de algunos datos (menos de 1kb) que me gustaría que los agentes de usuario pasen a otros sitios cuando se envían desde mi sitio. Para que los otros sitios verifiquen que yo fui el que creó la cadena, pensé en dos opciones.Cómo cifrar datos en php usando claves públicas/privadas?

  1. Los pings de servidor que vuelva a confirmar (como PayPal, openid, etc ..)
  2. utilizo claves públicas/privadas para probar que envió el mensaje (como PGP, DKIM, etc ..)

No quiero configurar HMAC porque eso significaría que tengo que usar claves personalizadas para cada sitio que sería un problema.

De esas dos opciones, parece que # 2 ahorraría en ancho de banda, lo que lo hace parecer una mejor opción.

Entonces, ¿cómo puede configurar pública que/privada criptografía de clave usando PHP y hay alguna desventajas?

Respuesta

9

Crearía los pares de claves públicas/privadas S/MIME usando OpenSSL y luego usaría el comando OpenSSL para hacer la encriptación &. Creo que esto es superior al uso de PGP porque openssl está incluido en la mayoría de los sistemas operativos Linux y PGP no. OpenSSL también está basado en estándares y generalmente es más fácil trabajar con él, una vez que tiene los comandos desactivados.

Lo recomendé en contra de una solución "pura PHP" (por PHP puro me refiero a hacer la criptografía en PHP, en lugar de usar PHP para llamar a una biblioteca existente o un ejecutable por separado). No quieres hacer criptografía masiva en PHP. Demasiado lento. Y desea usar OpenSSL, porque es de alto rendimiento y la seguridad es bien conocida.

Aquí está la magia.

Haciendo clave X.509:

$subj="/C=US/ST=California/L=Remote/O=Country Govt./OU=My Dept/CN=Mr. Agent/[email protected]" 
openssl req -x509 -newkey rsa:1024 -keyout mycert.key -out mycert.pem -nodes -subj $subj 

que pone la clave privada en mycert.key y la clave pública en mycert.pem. La clave privada no está protegida con contraseña.

Ahora, para firmar un mensaje con S/MIME:

openssl smime -sign -signer mycert.pem -inkey mycert.key <input >output 

Para cifrar un mensaje con S/MIME:

openssl smime -encrypt -recip yourcert.pem <input >output 

para descifrar un mensaje con S/MIME:

openssl smime -decrypt -inkey mycert.key -certfile mycert.pem <input >output 

También tengo algunas demostraciones sobre el uso de OpenSSL desde los enlaces de lenguaje C, pero no desde PHP.

+5

¿Por qué PHP [OpenSSL extensión] (http://us2.php.net/manual/en/book.openssl.php) ser más lento que llamar a OpenSSL sí mismo? El mismo código se ejecuta de cualquier manera. Dicho esto, hay otra razón para no hacerlo PHP-native: la extensión OpenSSL no puede hacer todo lo que se gasta en el binario de openssl cuando se trabaja con formatos de clave exóticos. – Charles

+2

I segundo el comentario de Charles. Es probable que la extensión PHP OpenSSL sea * más rápida *, no más lenta, porque usa las mismas API que las aplicaciones de línea de comando de openssl, pero sin la sobrecarga de creación de procesos. – Artefacto

+1

Oh, no sabía que PHP tenía extensiones OpenSSL. Deberías usarlos, entonces. Tengo código C++ que hace esto; ¿Debería publicarlo? – vy32

2

PGP es una buena opción: se implementa de forma correcta y completa (es decir, tiene poco margen para errores de seguridad con PGP). Creo que this SO question lo ayudará a interactuar con GnuPG. La pregunta es si los otros sitios verificarán y cómo lo harán. Debe cumplir con los requisitos del mecanismo de verificación o proporcionar su propio módulo que esos sitios usarán para la verificación.

También es posible que pueda usar OAuth o OpenID para identificar a los usuarios en esos otros sitios, pero no soy un experto en estas tecnologías.

2

Regla 1: No la implemente usted mismo, use una biblioteca.

¿Qué biblioteca? Here are my recommended PHP public-key cryptography libraries:

  1. Halite, depende de libsodium (pero hace hincapié en la simplicidad y facilidad de uso, además de la seguridad).
  2. libsodium, desde PECL
  3. EasyRSA, que implementa cifrado de clave pública y firmas de clave pública RSA seguras usando en los modos más seguros (NO PKCS1v1.5, nunca!)
  4. phpseclib, lo que lleva a cuestas fuera de EasyRSA .

En general, deseará libsodium si la seguridad es su objetivo. Si utilizas o no Halite es una cuestión de gusto.

6

Crear un par de claves privada y pública utilizando las funciones PHP OpenSSL:

// Configuration settings for the key 
$config = array(
    "digest_alg" => "sha512", 
    "private_key_bits" => 4096, 
    "private_key_type" => OPENSSL_KEYTYPE_RSA, 
); 

// Create the private and public key 
$res = openssl_pkey_new($config); 

// Extract the private key into $private_key 
openssl_pkey_export($res, $private_key); 

// Extract the public key into $public_key 
$public_key = openssl_pkey_get_details($res); 
$public_key = $public_key["key"]; 

A continuación, puede cifrar y descifrar utilizando las claves privadas y públicas como esta:

// Something to encrypt 
$text = 'This is the text to encrypt'; 

echo "This is the original text: $text\n\n"; 

// Encrypt using the public key 
openssl_public_encrypt($text, $encrypted, $public_key); 

$encrypted_hex = bin2hex($encrypted); 
echo "This is the encrypted text: $encrypted_hex\n\n"; 

// Decrypt the data using the private key 
openssl_private_decrypt($encrypted, $decrypted, $private_key); 

echo "This is the decrypted text: $decrypted\n\n"; 
+0

¿Quién debe conservar la clave pública y quién debe conservar la clave privada? ¿Deberíamos dar la clave pública al cliente o la clave privada? – Phantom007