白山网站设计,广州黄埔网站建设,辽宁建设工程,兰州注册公司加密和摘要的区别 ***摘要#xff1a;是从已知的数据中#xff0c;通过摘要计算出一个值#xff0c;一个数据对应一个或多个摘要的值 *** 比如#xff1a;md5 和 sha1 sha256 hash 就是得到一个特定的值 #xff0c;同一个数据得到的md5 是一样的#xff0c;不会改变的 比…加密和摘要的区别 ***摘要是从已知的数据中通过摘要计算出一个值一个数据对应一个或多个摘要的值 *** 比如md5 和 sha1 sha256 hash 就是得到一个特定的值 同一个数据得到的md5 是一样的不会改变的 比如password_hash 产生的是一个可以变化的摘要同一个数据每一次生成的都是不一样的结果当验证的时候可以使用password_verify 来验证是否正确 以下是上面的使用代码 $str hello huangjunhui;var_dump(md5($str));echo br/;var_dump(hash(md5,$str));echo br/;var_dump(sha1($str));echo br/;var_dump(hash(sha1,$str));echo br/;var_dump(hash(sha256,$str));echo br/;var_dump(hash(sha512,$str));echo br/;这里说一下 hash 的用法 hash($algo,$data); algo是散列的算法 如果想要查看 hash 可以支持哪些算法 可以使用 hash_algos() 函数 得到的数组就是 hash 支持的算法 以上的摘要都是唯一值的 同样还有一种算法不是唯一值的比如我们使用的 password_hash 函数 $str hello huangjunhui;$result password_hash($str,PASSWORD_DEFAULT);//得到加密的结果echo $result.br/; //$2y$10$4sFjS28dGe/DM5MQMQKPp.R.wWWqZYgHJQCHqGjo8vfPPKYrrBzl2//$2y$10$uPBE9MKkJh1r4NSk5VgzduUhrgeMLgnJXzmbghEdh8cK3swnvAXEmecho (int)password_verify($str,$result); //这里是一个布尔值强转了int上面可以看到 每一次 password_hash的结果都是不一样的 当验证的时候 却总是结果为 真所以这种方法一般都用在存储用户的密码到数据库就算数据库丢失也不会让用户的密码泄漏 上面的几个摘要方法有一个共同点就是 不可逆也就是说你想通过密文再获取到原文是不可能的 所以以上的算法都属于摘要算法 加密解密
能加密解密就是说我不仅可以从原文得到密文也可以从密文在反过来得到原文 主要有两种方式 一种是对称加密 一种是非对称加密
php 的加解密用的 openssl_encrypt 和 openssl_decrype 顺便说一句 php之前有一个加密的方法 mcrypt 方法过时了
openssl 的使用注意事项
我在 windows 系统中使用的 openssl , 首先要在 php.ini中打开 openssl的扩展同时还要找到openssl 的 配置文件openssl.cnf的路径在会使用的时候要指明 openssl.cnf 的路径 不然会报错 可以看到phpinfo中的 openssl 的配置件在 /usr/local/ssl/openssl.cnf 路径中window 中根本没有这个路径所以我们在使用 php 的 openssl的时候要在配置中指明配置文件的路径
对称加密就是加解密过程中所使用的密钥是一样的
对称加密的算法 通常有 AES 和 DES 两中下面我们来看看 PHP 中的对称加密 对称加密通常用于内部的系统 比如本地的文件加密 加密时会产生一上 iv向量 在进行网络传输时 是要和密文一起传给接收方的 双方密主要保证 密钥的安全 不泄漏就可以了 以下是 生成一个密文 再解密这个密文的代码
//生成一个密文并返回 密文和iv向量
public function openssl(){$str hello world,huang junhui; //待加密的字符串$key openssl_random_pseudo_bytes(16); //这里相当于就是一个密钥了 加密和解密时的密码必须是一样的才可以dump(strlen($key)); //int(16)$keybase64 base64_encode($key); //因为上一步生成的 key是一个 二进制的数据 显示出来是乱码 所在要想显示就要base64一下$key1 base64_decode($keybase64);dump($keybase64);dump(strlen($keybase64)); //int(24)$cipher AES-128-CBC; //这里是加密算法的名称 可以使用 openssl_get_cipher_methods() 查看所有支持的加密算法名称$ivLen openssl_cipher_iv_length($cipher); //获取算法对应初始化向量的长度$iv openssl_random_pseudo_bytes($ivLen); //随机生成一个初始化向量 //这里也可以手写一个长度为 $ivLen 的字符串此例中$ivLen是16 所以可以随便写一个 ”sfasfasdfsdfasdf“$encrypted openssl_encrypt($str,$cipher,$key,OPENSSL_RAW_DATA,$iv);//$encrypted openssl_encrypt($str,$cipher,$keybase64,OPENSSL_RAW_DATA,sfasfasdfsdfasdf); //字符长度必需是16位的 $ivLen的长度//这里使用 $key 和 $keybase64 不影响效果长度不一样 一个是16一个是24 也就是说 密钥的长度是可以任意长度的 只要加密和解密的时侯使用同一个 key就可以了//由于对称加密的特殊性 当传输数据的时候是要把iv明文一起传输线接收方的所以当我们返回给请求方的时候要把 密文加上 $iv 一起传送给前端又因为$iv是一个二进制数据所以要base64一下才可以在网络中传输// dump(base64_encode($encrypted.:.$iv));//接收端接到数据之后首先base64_decode ,然后使用 : 把密文和向量数据分开return base64_encode($encrypted.:::.$iv);//$decrypted openssl_decrypt($encrypted,$cipher,$key,OPENSSL_RAW_DATA,$iv);//$decrypted openssl_decrypt($encrypted,$cipher,$keybase64,OPENSSL_RAW_DATA,sfasfasdfsdfasdf);//dump($decrypted);}//解密密文public function decodeopenssl(){//传入的加密结果 PDwc77SaX/WcpipdClDx3dYCQBjwWarDswmcwkYKUYU6OjqwKjMwKxcMKU34FYTRhqoj//加密时使用的 key XHvcRREJw5vlJKP8AoR39A//$base64str input(secret_content);$str base64_decode(PDwc77SaX/WcpipdClDx3dYCQBjwWarDswmcwkYKUYU6OjqwKjMwKxcMKU34FYTRhqoj);dump($str);$secretArr explode(:::,$str);$secretbody $secretArr[0];$iv $secretArr[1];$key base64_decode(XHvcRREJw5vlJKP8AoR39A);$cipher AES-128-CBC;$decrypted openssl_decrypt($secretbody,$cipher,$key,OPENSSL_RAW_DATA,$iv);dump($decrypted);}对称加密是双方都知道密钥的情况下使用的最主要的是密钥的安全iv 明文传输没关系
非对称加密
非对称加密可以用作对数据的加密 也可以用作对数据的签名 加密和签名的理解 加密的时候是 返回给接收方一段无序的数据 要对方解密才可以使用签名是 把原数据给接收方并在返回的数据中 带上一个由原数据生成的一个签名数据 public function openssl(){$str hello world,huang junhui; //待加密的字符串//上面说过在windows中openssl 的配置文件的路径是要自己找定的 系统默认的路径不是正确的所以我们要进 配置文的的路径的配置//两种方式 一种是在系统环境变量中配置 环境变量名OPENSSL_CONF 变量值 就是openssl.cnf文件的位置 D:\laragon\bin\apache\httpd-2.4.54-win64-VS16\conf\openssl.cnf//另一种方式在config数组中配置 config D:\laragon\bin\apache\httpd-2.4.54-win64-VS16\conf\openssl.cnf , 注意config 的结构$config [configD:\laragon\bin\apache\httpd-2.4.54-win64-VS16\conf\openssl.cnf,digest_alg sha512, //摘要算法或签名的算法 非必填private_key_bits 2048, //私钥的长度 512 1024 2048 4096 通常选1024或2048private_key_type OPENSSL_KEYTYPE_RSA, //加密类型 通常可以选择OPENSSL_KEYTYPE_DSA、 OPENSSL_KEYTYPE_DH、 OPENSSL_KEYTYPE_RSA 或 OPENSSL_KEYTYPE_EC。 默认值是 OPENSSL_KEYTYPE_RSA。];//创建私钥和公钥资源$res openssl_pkey_new($config); //注意这里是一个包含了公私钥的资源//资源中获取私钥 公私钥资源 生成的私钥 第三个参数是可以加一些盐值 第四个参数是 上面的配置项openssl_pkey_export($res, $private_key, null, $config);//dump($private_key);//从资源中获取公钥数组信息$public_key_arr openssl_pkey_get_details($res);$public_key $public_key_arr[key];dump($public_key);//这样我们就生成了一对公私钥 我们可以把每个生成的公私钥保存到数据库得到一个数据库的编号然后把公钥数据传给请求方请求方使用公钥加密数据之后 再返回给服务器 服务器使用私钥解密//签名 //签名是用公钥签名使用私钥来验证签名openssl_sign($str,$sign,$private_key,OPENSSL_ALGO_SHA1);dump(openssl_verify($str,$sign,$public_key,OPENSSL_ALGO_SHA1));//有了上面的公钥我们就可以用来加密、openssl_public_encrypt($str,$encrypted_data,$public_key);dump($encrypted_data);//解密数据openssl_private_decrypt($encrypted_data,$decrypted_data,$private_key);dump($decrypted_data);}以上就是openssl 的用法 下面是一个 封装的 RSA 类 , 可以做参考
?php/*** RSA签名类*/
class Rsa
{public $publicKey ;public $privateKey ;private $_privKey;/*** * private key*/private $_pubKey;/*** * public key*/private $_keyPath;/*** * the keys saving path*//*** * the construtor,the param $path is the keys saving path* param string $publicKey 公钥* param string $privateKey 私钥*/public function __construct($publicKey null, $privateKey null){$this-setKey($publicKey, $privateKey);}/*** 设置公钥和私钥* param string $publicKey 公钥* param string $privateKey 私钥*/public function setKey($publicKey null, $privateKey null){if (!is_null($publicKey)) {$this-publicKey $publicKey;}if (!is_null($privateKey)) {$this-privateKey $privateKey;}}/*** * setup the private key*/private function setupPrivKey(){if (is_resource($this-_privKey)) {return true;}$pem chunk_split($this-privateKey, 64, \n);$pem -----BEGIN PRIVATE KEY-----\n . $pem . -----END PRIVATE KEY-----\n;$this-_privKey openssl_pkey_get_private($pem);return true;}/*** * setup the public key*/private function setupPubKey(){if (is_resource($this-_pubKey)) {return true;}$pem chunk_split($this-publicKey, 64, \n);$pem -----BEGIN PUBLIC KEY-----\n . $pem . -----END PUBLIC KEY-----\n;$this-_pubKey openssl_pkey_get_public($pem);return true;}/*** * encrypt with the private key*/public function privEncrypt($data){if (!is_string($data)) {return null;}$this-setupPrivKey();$r openssl_private_encrypt($data, $encrypted, $this-_privKey);if ($r) {return base64_encode($encrypted);}return null;}/*** * decrypt with the private key*/public function privDecrypt($encrypted){if (!is_string($encrypted)) {return null;}$this-setupPrivKey();$encrypted base64_decode($encrypted);$r openssl_private_decrypt($encrypted, $decrypted, $this-_privKey);if ($r) {return $decrypted;}return null;}/*** * encrypt with public key*/public function pubEncrypt($data){if (!is_string($data)) {return null;}$this-setupPubKey();$r openssl_public_encrypt($data, $encrypted, $this-_pubKey);if ($r) {return base64_encode($encrypted);}return null;}/*** * decrypt with the public key*/public function pubDecrypt($crypted){if (!is_string($crypted)) {return null;}$this-setupPubKey();$crypted base64_decode($crypted);$r openssl_public_decrypt($crypted, $decrypted, $this-_pubKey);if ($r) {return $decrypted;}return null;}/*** 构造签名* param string $dataString 被签名数据* return string*/public function sign($dataString){$this-setupPrivKey();$signature false;openssl_sign($dataString, $signature, $this-_privKey);return base64_encode($signature);}/*** 验证签名* param string $dataString 被签名数据* param string $signString 已经签名的字符串* return number 1签名正确 0签名错误*/public function verify($dataString, $signString){$this-setupPubKey();$signature base64_decode($signString);$flg openssl_verify($dataString, $signature, $this-_pubKey);return $flg;}public function __destruct(){is_resource($this-_privKey) openssl_free_key($this-_privKey);is_resource($this-_pubKey) openssl_free_key($this-_pubKey);}
}
$publicKey MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKZ1mKTymRoGKnHiP1xAy4aiyt5r0BscCZnDAonCrMFZ4kBGriPNHxEaLr5lfBnMKw7k6i2dsFPSEZooTvqtPUCAwEAAQ;
$privateKey MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApnWYpPKZGgYqceI/XEDLhqLK3mvQGxwJmcMCicKswVniQEauI80fERouvmV8GcwrDuTqL7Z2wU9IRmihOq09QIDAQABAkBunx3nGHXYjppsfn7iyTdI7Agfy/0xWyB3rpEiGGgfemjcRFaeq5SC2vUNXsrEOY5gbUSQmFxH//Cym18NAiEA1z1cZx/Q9cbIjFPwp1aK5CVFDXDcfbi/AQgAkVs0/cCIQDF2fr23AoBslcOC4S0yAx94AbgxCntYuRqztxybsrcwIgMW86ZcT87TX2oaQ1xXk6vC68zqN6fBZEE7Wu1Fa1pAkCIElmOJP3qfAc/AAljdIwLHlqWgJwl3674CU9Bfui2bDAiEA0CKJpF8x7KANCcopEQC93PsbIztuML322LOfDV1Lw/k;
$rsanew Rsa($publicKey,$privateKey);
$strabc;
echo 原始数据:.$str;
echo br/hr;
$res$rsa-privEncrypt($str);
echo 私钥加密数据:.$res;
echo br/;$res2$rsa-pubDecrypt($res);
echo 公钥解密数据:.$res2;
echo br/hr;$res3$rsa-pubEncrypt($str);
echo 公钥加密数据:.$res3;
echo br/;$res4$rsa-privDecrypt($res3);
echo 私钥解密数据:.$res4;
echo br/hr;echo 签名数据:.$str;
$res5$rsa-sign($str);
echo br/;
echo 签名结果:.$res5;
$res6$rsa-verify($str,$res5);
echo br/;
echo 验证签结果:.$res6;