2011-01-07 16 views
9

Ho una piccola stringa di alcuni dati (meno di 1kb) che vorrei che gli agenti utente passassero ad altri siti quando vengono inviati dal mio sito. Affinché gli altri siti possano verificare che io sia quello che ha creato la stringa, ho pensato a due opzioni.Come crittografare i dati in php utilizzando le chiavi pubbliche/private?

  1. I ping server mi torna per confermare (come paypal, OpenID, ecc ..)
  2. Io uso le chiavi pubbliche/private per dimostrare che ho inviato il messaggio (come PGP, DKIM, ecc ..)

Non voglio impostare HMAC perché ciò significherebbe che devo usare chiavi personalizzate per ogni sito che sarebbe un problema.

Fuori da queste due scelte sembra che # 2 risparmierà sulla larghezza di banda che lo fa sembrare una scelta migliore.

Quindi, come è possibile impostare la crittografia a chiave pubblica/privata utilizzando PHP e ci sono degli aspetti negativi?

risposta

9

Vorrei creare coppie di chiavi pubbliche/private S/MIME utilizzando OpenSSL e quindi utilizzare il comando OpenSSL per eseguire la crittografia & decrittografia. Credo che questo sia superiore all'utilizzo di PGP perché openssl è incluso nella maggior parte dei sistemi operativi Linux e PGP no. OpenSSL è anche basato su standard e generalmente più semplice da utilizzare, una volta che i comandi sono stati disattivati.

Mi sono raccomandato contro una soluzione "puro-PHP" (per puro PHP intendo la crittografia in PHP, piuttosto che usare PHP per chiamare una libreria esistente o un eseguibile separato). Non vuoi fare la crittografia collettiva in PHP. Troppo lento. E tu vuoi usare OpenSSL, perché sono alte prestazioni e la sicurezza è ben compresa.

Ecco la magia.

Per effettuare una chiave 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 

che mette la chiave privata nel mycert.key e la chiave pubblica in mycert.pem. La chiave privata non è protetta da password.

Ora, per firmare un messaggio con S/MIME:

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

Per crittografare un messaggio con S/MIME:

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

Per decifrare un messaggio con S/MIME:

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

Ho anche alcune dimostrazioni sull'utilizzo di OpenSSL dai collegamenti del linguaggio C, ma non da PHP.

+5

Perché sarebbe di PHP [OpenSSL estensione] (http://us2.php.net/manual/en/book.openssl.php) essere più lento di chiamare OpenSSL stesso? Lo stesso codice viene eseguito in entrambi i modi. Detto questo, c'è un altro motivo per non farlo PHP nativo: l'estensione OpenSSL non può fare tutto ciò che bombarda con il binario openssl quando lavora con formati di chiave esotici. – Charles

+2

I secondo commento di Carlo. L'estensione PHP OpenSSL sarà probabilmente * più veloce *, non più lenta, perché usa le stesse API delle applicazioni della riga di comando di openssl, ma senza il sovraccarico di creazione del processo. – Artefacto

+1

Oh, non sapevo che PHP avesse estensioni OpenSSL. Dovresti usarli, allora. Ho codice C++ che fa questo; dovrei postarlo? – vy32

2

PGP è una buona opzione - è implementata correttamente e completamente (ovvero, si ha poco spazio per errori di sicurezza con PGP). Penso che lo this SO question ti aiuterà nell'interfacciamento con GnuPG. La domanda è se e come gli altri siti verificheranno la tua firma. È necessario conformarsi ai requisiti del meccanismo di verifica o fornire il proprio modulo che tali siti utilizzeranno per la verifica.

Inoltre, è possibile utilizzare OAuth o OpenID per identificare gli utenti su tali altri siti, ma non sono un esperto in queste tecnologie.

2

Regola 1: non implementare da soli, utilizzare una libreria.

Quale libreria? Here are my recommended PHP public-key cryptography libraries:

  1. Halite, dipende libsodium (ma sottolinea la semplicità e la facilità d'uso oltre alla sicurezza).
  2. libsodium, da PECL
  3. EasyRSA, che implementa le firme sicure a chiave pubblica di cifratura e chiave pubblica RSA utilizzano nei modi più sicuri (NON PKCS1v1.5, mai!)
  4. phpseclib, che EasyRSA piggybacks off di .

In generale, ti consigliamo libsodium se la sicurezza è il tuo obiettivo. Se usi o meno l'Halite è una questione di gusti.

6

Creazione di una coppia di chiavi pubblica e privata utilizzando le funzioni 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"]; 

È quindi possibile crittografare e decrittografare utilizzando le chiavi pubbliche e private come questo:

// 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

Chi deve mantenere la chiave pubblica e chi deve conservare la chiave privata? Dovremmo dare la chiave pubblica al cliente o alla chiave privata? – Phantom007

Problemi correlati