Comment chiffrer des données en php en utilisant des clés publiques / privées?

j'ai une petite chaîne de quelques données (moins de 1kb) que je voudrais que les agents utilisateurs passent à d'autres sites quand ils sont envoyés à partir de mon site. Pour que les autres sites vérifient que j'étais celui qui a créé la chaîne j'ai pensé à deux options.

  1. le serveur me renvoie pour confirmer (comme paypal, openid, etc..)
  2. j'utilise des clés publiques/privées pour prouver que j'ai envoyé le message (comme PGP, DKIM, etc..)

Je ne veux pas configurer HMAC parce que cela signifierait que je dois utiliser des clés personnalisées pour chaque site qui serait une douleur.

de ces deux choix, il semble que #2 économiserait sur la bande passante ce qui le fait paraître comme un meilleur choix.

alors comment pouvez-vous configurer la cryptographie à clé publique/privée en utilisant PHP et y a-t-il des inconvénients?

9
demandé sur Scott Arciszewski 2011-01-07 22:39:24

5 réponses

je créerais S/MIME Public/private keypairs en utilisant OpenSSL et puis j'utiliserais la commande OpenSSL pour faire le chiffrement et le déchiffrement. Je pense que C'est mieux que D'utiliser PGP car openssl est inclus dans la plupart des systèmes d'exploitation linux et PGP ne l'est pas. OpenSSL est également basé sur des normes et généralement plus facile à travailler, une fois que vous avez les commandes désactivées.

j'ai déconseillé une solution "pur-PHP" (par pur-PHP j'entends faire la cryptographie en PHP, plutôt que d'utiliser PHP pour appeler une bibliothèque existante ou un exécutable séparé). Vous ne voulez pas faire de crypto en vrac en PHP. Trop lent. Et vous voulez utiliser OpenSSL, parce que c'est une haute performance et la sécurité est bien comprise.

Voici la magie.

pour créer une clé X. 509:

$subj="/C=US/ST=California/L=Remote/O=Country Govt./OU=My Dept/CN=Mr. Agent/emailAddress=agent@investiations.com"
openssl req -x509 -newkey rsa:1024 -keyout mycert.key -out mycert.pem -nodes -subj $subj

Qui met la clé privée dans mycert.la clé et la clé publique dans mycert.pem. La clé privée n'est pas protégée par mot de passe.

maintenant, à signer un message avec S / MIME:

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

pour chiffrer un message avec S / MIME:

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

pour déchiffrer un message avec S / MIME:

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

j'ai aussi quelques démos sur L'utilisation D'OpenSSL à partir des liens du langage C, mais pas de PHP.

9
répondu vy32 2012-08-18 15:14:07

la Création d'une clé privée et publique de la paire en utilisant le PHP fonctions d'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"];

vous pouvez alors chiffrer et déchiffrer en utilisant les clés privées et publiques comme ceci:

// 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";
7
répondu Eborbob 2016-02-09 10:08:15

Règle 1: Ne l'implémentez pas vous-même, utilisez une bibliothèque.

quelle bibliothèque? Voici mes bibliothèques de cryptographie à clé publique PHP recommandées :

  1. Halite , dépend de libsodium (mais met l'accent sur la simplicité et la facilité d'utilisation en plus de la sécurité).
  2. libsodium , à partir de PECL
  3. EasyRSA , qui implémente le cryptage sécurisé des clés publiques et des signatures de clés publiques en utilisant RSA dans les modes les plus sécurisés (pas PKCS1v1.5, jamais!)
  4. phpseclib , qui EasyRSA piggybacks off.

en général, vous aurez besoin de libsodium si la sécurité est votre objectif. Si vous n'utilisez Halite est une question de goût.

3
répondu Scott Arciszewski 2015-12-09 07:48:49

PGP est une bonne option - il est mis en œuvre correctement et complètement (i.e. vous avez peu de place pour les erreurs de sécurité avec PGP). Je pense que cette question ainsi vous aidera à interfacer avec GnuPG. La question Est de savoir si et comment les autres sites vérifieront votre signature. Vous devez vous conformer aux exigences de leur mécanisme de vérification ou fournir votre propre module que ces sites utiliseront pour la vérification.

C'est aussi possible que vous pouvez utiliser OAuth ou OpenID pour identifier les utilisateurs sur ces autres sites, mais je ne suis pas un expert dans ces technologies.

2
répondu Eugene Mayevski 'Allied Bits 2017-05-23 10:30:49

j'ai écrit un exemple de chiffrement et de déchiffrement avec openSSL en PHP et Python

http://glynrob.com/php/hashing-and-public-key-encryption /

Github le code source disponible.

N'oubliez pas que la clé privée doit être disponible à l'emplacement de décryptage pour que cela fonctionne.

1
répondu GlynRob 2013-10-19 22:56:02