Pour la plupart des sites Web sur Internet, les données des utilisateurs sont soumises directement au CGI back-end en texte clair, et la plupart des accès entre les serveurs sont transmis en texte clair, qui peut être surveillé par certaines personnes ayant des arrière-pensées par certains moyens. Les sites Web ayant des exigences de sécurité plus élevées, comme les banques et les grandes entreprises, utiliseront HTTPS pour crypter le processus de communication.
Mais utiliser HTTPS coûte extrêmement cher. Il ne s’agit pas seulement de l’achat de certificats CA, mais plus important encore du sérieux goulot d’étranglement en termes de performances. La solution actuelle ne peut consister qu’à utiliser un équipement d’accélération matérielle SSL spécialisé tel que le BIGIP de F5. Par conséquent, certains sites Web choisissent simplement de simuler SSL et d’utiliser RSA et AES pour chiffrer les données transmises. Le principe est illustré dans la figure ci-dessous :
Cela améliore dans une certaine mesure la sécurité de la transmission des données. Mais pour la plupart des sites Web, la plupart des données n’ont pas besoin d’être aussi strictes et seules certaines petites données importantes peuvent être cryptées de manière sélective, comme les mots de passe. Pour le cryptage de petits volumes de données, il n'est pas nécessaire d'utiliser l'intégralité du processus, utilisez simplement RSA, ce qui simplifiera grandement le processus.
Pourquoi la taille des données est-elle petite ? Car comparé au chiffrement symétrique, l’algorithme de chiffrement asymétrique deviendra extrêmement lent à mesure que la quantité de données augmente. Par conséquent, des algorithmes de chiffrement symétriques sont généralement utilisés pour le chiffrement réel des données. Par conséquent, les fonctions étendues de chiffrement à clé publique et privée openssl en PHP ne prennent en charge que les petites données (117 octets pour le chiffrement et 128 octets pour le déchiffrement).
Il existe sur Internet des bibliothèques d'algorithmes Javascript open source pour AES et RSA, qui peuvent être directement implémentées en PHP via des extensions associées (l'algorithme AES peut être implémenté via la fonction liée à mcrypt, RSA peut être implémenté via les fonctions associées d'openssl), au lieu d'utiliser du code PHP pur pour implémenter l'algorithme comme mentionné sur Internet. En raison de contraintes d'espace, cet article présente uniquement la mise en œuvre de la communication cryptée RSA entre Javascript et PHP, en prenant comme exemple le cryptage des mots de passe.
Premier code :
Cryptage frontal
Chargez d'abord trois fichiers de bibliothèque RSA js, qui peuvent être téléchargés ici http://www.ohdave.com/rsa/
$(document).ready(function(){ //十六进制公钥 var rsa_n = "C34E069415AC02FC4EA5F45779B7568506713E9210789D527BB89EE462662A1D0E94285E1A764F111D553ADD7C65673161E69298A8BE2212DF8016787E2F4859CD599516880D79EE5130FC5F8B7F69476938557CD3B8A79A612F1DDACCADAA5B6953ECC4716091E7C5E9F045B28004D33548EC89ED5C6B2C64D6C3697C5B9DD3"; $("#submit").click(function(){ setMaxDigits(131); //131 => n的十六进制位数/2+3 var key = new RSAKeyPair("10001", '', rsa_n); //10001 => e的十六进制 var password = $("#password").val(); password = encryptedString(key, password);//美中不足,不支持汉字~ $("#password").val(password); $("#login").submit(); }); });
Fonction de cryptage PHP
/** * 私钥解密 * * @param string 密文(base64编码) * @param string 密钥文件(.pem) * @param string 密文是否来源于JS的RSA加密 * @return string 明文 */ function privatekey_decodeing($crypttext, $fileName,$fromjs = FALSE) { $key_content = file_get_contents($fileName); $prikeyid = openssl_get_privatekey($key_content); $crypttext = base64_decode($crypttext); $padding = $fromjs ? OPENSSL_NO_PADDING : OPENSSL_PKCS1_PADDING; if (openssl_private_decrypt($crypttext, $sourcestr, $prikeyid, $padding)) { return $fromjs ? rtrim(strrev($sourcestr), "/0") : "".$sourcestr; } return FALSE; }
Fonction de décryptage PHP
/** * 私钥解密 * * @param string 密文(base64编码) * @param string 密钥文件(.pem) * @param string 密文是否来源于JS的RSA加密 * @return string 明文 */ function privatekey_decodeing($crypttext, $fileName,$fromjs = FALSE) { $key_content = file_get_contents($fileName); $prikeyid = openssl_get_privatekey($key_content); $crypttext = base64_decode($crypttext); $padding = $fromjs ? OPENSSL_NO_PADDING : OPENSSL_PKCS1_PADDING; if (openssl_private_decrypt($crypttext, $sourcestr, $prikeyid, $padding)) { return $fromjs ? rtrim(strrev($sourcestr), "/0") : "".$sourcestr; } return FALSE; }
Code de test
define("CRT", "ssl/server.crt"); //公钥文件 define("PEM", "ssl/server.pem"); //私钥文件 //JS->PHP 测试 $data = $_POST['password']; $txt_en = base64_encode(pack("H*", $data)); //转成base64格式 $txt_de = privatekey_decodeing($txt_en, PEM, TRUE); var_dump($txt_de); //PHP->PHP 测试 $data = "测试TEST"; //PHP端支持汉字:D $txt_en = publickey_encodeing($data, CRT); $txt_de = privatekey_decodeing($txt_en, PEM); var_dump($txt_de);
Le code est posté , Il y a quelques choses qui doivent être expliquées. L'obtention de la clé publique hexadécimale est la clé. Étant donné que la clé est obtenue à partir du certificat x.509, vous devez d'abord générer la clé et le fichier de certificat (la clé de 1024 bits utilisée dans cet article). Veuillez rechercher sur Google la méthode de génération spécifique :P. Ici, nous nous concentrons sur la façon d’en obtenir la clé hexadécimale.
Lisez la clé hexadécimale du fichier. J'ai déjà essayé de nombreuses méthodes. On dit sur Internet que les données sont codées en ASN.1...囧~ Finalement, j'ai accidentellement remarqué que openssl sous le Le shell Linux ressemble à Peut être extrait d'un fichier de clé privée (clé ou pem).
openssl asn1parse -out temp.ans -i -inform PEM < server.pem
Les résultats affichés sont les suivants :
D'ici, vous pouvez enfin voir les dix requis en Javascript Clé publique hexadécimale : D
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!