精华内容
下载资源
问答
  • 本文详细介绍了PHP一个简单的对称加密函数实现数据的加密解密,详细的介绍了对称加密和非对称加密,有需要的可以了解一下。
  • 本文详细介绍了PHP一个简单的对称加密函数实现数据的加密解密,详细的介绍了对称加密和非对称加密,有需要的可以了解一下。项目中有一个地方用到了将用户ID加密、传至下个接点进行反解的需求。(原谅我不能透漏太多-_...

    本文详细介绍了PHP一个简单的对称加密函数实现数据的加密解密,详细的介绍了对称加密和非对称加密,有需要的可以了解一下。

    项目中有一个地方用到了将用户ID加密、传至下个接点进行反解的需求。(原谅我不能透漏太多-_-!),第一个想到的就是康盛Ucenter中的一个函数,后来搜了下,在简明魔法中也找到了个简单的方法,遂整合了下,形成了自己使用的函数。

    一、对称加密

    发送方将明文使用密钥和算法处理成密文发送出去,接收方使用密钥和算法将密文处理成明文,发收信双方使用同一个密钥对数据进行加密和解密。

    因为使用同一个密钥加密、解密,所以安全性上不仅与算法有关,密钥的安全也很重要。

    当然并不是密钥越复杂越好,相反密钥通常比较小的,因为虽然密钥越大,加密越强,但加密与解密的过程越慢,所以密钥的大小既要照顾到安全性,也要照顾到效率。

    毕竟对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高,没了效率高这一优势,还不如直接用非对称加密。

    此外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。

    对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。

    二、非对称加密

    非对称加密相对来说,就安全很多了,它使用了一对密钥,公开密钥和私有密钥,分别用来进行加密和解密。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。

    最常见的非对称加密,应该就是银行系统,支付平台了。比如我们申请支付宝或者银联支付的接口时,会得到一个公钥,商城中进行支付是,用公钥将信息加密提交给平台,平台使用密钥对你的信息解密,进行支付操作等。

    虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们一般处理的话,大部分是用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去,回想一下你申请到的支付接口,是不是给了你一对密钥呢?^.^

    三、结合使用

    对称性加密速度快,发送大量数据时用比较好。非对称加密加密和解密花费时间长、速度慢,只适合对少量数据进行加密,但是,非对称加密的安全性是极高的。

    扬长避短:将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。

    项目中使用的方法不宜透露,只在这里列出两个其他的例子吧。第一个是ucenter中的,第二个是简明魔法中看到的。

    需要注意的是,由于是base64算法,加密后的字符串有可能会出现 + \ ,如果是用在url中,是不友好的,可以在外部或改下方法,正则验证递归调取下。

    /**

    * 字符串加密以及解密函数

    * @param string $string 原文或者密文

    * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE

    * @param string $key 密钥

    * @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效

    * @return string 处理后的 原文或者 经过 base64_encode 处理后的密文

    */

    function _authcode ($string, $operation = 'DECODE', $key = 'Ruesin', $expiry = 0)

    {

    $ckey_length = 4;

    $key = md5($key);

    $keya = md5(substr($key, 0, 16));

    $keyb = md5(substr($key, 16, 16));

    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0,

    $ckey_length) : substr(md5(microtime()), - $ckey_length)) : '';

    $cryptkey = $keya . md5($keya . $keyc);

    $key_length = strlen($cryptkey);

    $string = $operation == 'DECODE' ? base64_decode(

    substr($string, $ckey_length)) : sprintf('%010d',

    $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) .

    $string;

    $string_length = strlen($string);

    $result = '';

    $box = range(0, 255);

    $rndkey = array();

    for ($i = 0; $i <= 255; $i ++) {

    $rndkey[$i] = ord($cryptkey[$i % $key_length]);

    }

    for ($j = $i = 0; $i < 256; $i ++) {

    $j = ($j + $box[$i] + $rndkey[$i]) % 256;

    $tmp = $box[$i];

    $box[$i] = $box[$j];

    $box[$j] = $tmp;

    }

    for ($a = $j = $i = 0; $i < $string_length; $i ++) {

    $a = ($a + 1) % 256;

    $j = ($j + $box[$a]) % 256;

    $tmp = $box[$a];

    $box[$a] = $box[$j];

    $box[$j] = $tmp;

    $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));

    }

    if ($operation == 'DECODE') {

    if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&

    substr($result, 10, 16) ==

    substr(md5(substr($result, 26) . $keyb), 0, 16)) {

    return substr($result, 26);

    } else {

    return '';

    }

    } else {

    return $keyc . str_replace('=', '', base64_encode($result));

    }

    }

    /*********************************************************************

    函数名称:encrypt

    函数作用:加密解密字符串

    使用方法:

    加密 :encrypt('str','E','nowamagic');

    解密 :encrypt('被加密过的字符串','D','nowamagic');

    参数说明:

    $string :需要加密解密的字符串

    $operation:判断是加密还是解密:E:加密 D:解密

    $key :加密的钥匙(密匙);

    *********************************************************************/

    function encrypt($string,$operation,$key='')

    {

    $key=md5($key);

    $key_length=strlen($key);

    $string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string;

    $string_length=strlen($string);

    $rndkey=$box=array();

    $result='';

    for($i=0;$i<=255;$i++)

    {

    $rndkey[$i]=ord($key[$i%$key_length]);

    $box[$i]=$i;

    }

    for($j=$i=0;$i<256;$i++)

    {

    $j=($j+$box[$i]+$rndkey[$i])%256;

    $tmp=$box[$i];

    $box[$i]=$box[$j];

    $box[$j]=$tmp;

    }

    for($a=$j=$i=0;$i

    {

    $a=($a+1)%256;

    $j=($j+$box[$a])%256;

    $tmp=$box[$a];

    $box[$a]=$box[$j];

    $box[$j]=$tmp;

    $result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));

    }

    if($operation=='D')

    {

    if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8))

    {

    return substr($result,8);

    }

    else

    {

    return'';

    }

    }

    else

    {

    return str_replace('=','',base64_encode($result));

    }

    }

    以上就是本文的全部内容,希望对大家的学习有所帮助。

    相关推荐:

    展开全文
  • 项目中有一个地方用到了...一、对称加密发送方将明文使用密钥和算法处理成密文发送出去,接收方使用密钥和算法将密文处理成明文,发收信双方使用同一个密钥对数据进行加密和解密。因为使用同一个密钥加密、解密,所...

    项目中有一个地方用到了将用户ID加密、传至下个接点进行反解的需求。(原谅我不能透漏太多-_-!),第一个想到的就是康盛Ucenter中的一个函数,后来搜了下,在简明魔法中也找到了个简单的方法,遂整合了下,形成了自己使用的函数。

    一、对称加密

    发送方将明文使用密钥和算法处理成密文发送出去,接收方使用密钥和算法将密文处理成明文,发收信双方使用同一个密钥对数据进行加密和解密。

    因为使用同一个密钥加密、解密,所以安全性上不仅与算法有关,密钥的安全也很重要。

    当然并不是密钥越复杂越好,相反密钥通常比较小的,因为虽然密钥越大,加密越强,但加密与解密的过程越慢,所以密钥的大小既要照顾到安全性,也要照顾到效率。

    毕竟对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高,没了效率高这一优势,还不如直接用非对称加密。

    此外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。

    对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。

    二、非对称加密

    非对称加密相对来说,就安全很多了,它使用了一对密钥,公开密钥和私有密钥,分别用来进行加密和解密。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。

    最常见的非对称加密,应该就是银行系统,支付平台了。比如我们申请支付宝或者银联支付的接口时,会得到一个公钥,商城中进行支付是,用公钥将信息加密提交给平台,平台使用密钥对你的信息解密,进行支付操作等。

    虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们一般处理的话,大部分是用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去,回想一下你申请到的支付接口,是不是给了你一对密钥呢?^.^

    三、结合使用

    对称性加密速度快,发送大量数据时用比较好。非对称加密加密和解密花费时间长、速度慢,只适合对少量数据进行加密,但是,非对称加密的安全性是极高的。

    扬长避短:将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。

    项目中使用的方法不宜透露,只在这里列出两个其他的例子吧。第一个是ucenter中的,第二个是简明魔法中看到的。

    需要注意的是,由于是base64算法,加密后的字符串有可能会出现 + \ ,如果是用在url中,是不友好的,可以在外部或改下方法,正则验证递归调取下。

    /**

    * 字符串加密以及解密函数

    * @param string $string 原文或者密文

    * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE

    * @param string $key 密钥

    * @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效

    * @return string 处理后的 原文或者 经过 base64_encode 处理后的密文

    */

    function _authcode ($string, $operation = 'DECODE', $key = 'Ruesin', $expiry = 0)

    {

    $ckey_length = 4;

    $key = md5($key);

    $keya = md5(substr($key, 0, 16));

    $keyb = md5(substr($key, 16, 16));

    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0,

    $ckey_length) : substr(md5(microtime()), - $ckey_length)) : '';

    $cryptkey = $keya . md5($keya . $keyc);

    $key_length = strlen($cryptkey);

    $string = $operation == 'DECODE' ? base64_decode(

    substr($string, $ckey_length)) : sprintf('%010d',

    $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) .

    $string;

    $string_length = strlen($string);

    $result = '';

    $box = range(0, 255);

    $rndkey = array();

    for ($i = 0; $i <= 255; $i ++) {

    $rndkey[$i] = ord($cryptkey[$i % $key_length]);

    }

    for ($j = $i = 0; $i < 256; $i ++) {

    $j = ($j + $box[$i] + $rndkey[$i]) % 256;

    $tmp = $box[$i];

    $box[$i] = $box[$j];

    $box[$j] = $tmp;

    }

    for ($a = $j = $i = 0; $i < $string_length; $i ++) {

    $a = ($a + 1) % 256;

    $j = ($j + $box[$a]) % 256;

    $tmp = $box[$a];

    $box[$a] = $box[$j];

    $box[$j] = $tmp;

    $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));

    }

    if ($operation == 'DECODE') {

    if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&

    substr($result, 10, 16) ==

    substr(md5(substr($result, 26) . $keyb), 0, 16)) {

    return substr($result, 26);

    } else {

    return '';

    }

    } else {

    return $keyc . str_replace('=', '', base64_encode($result));

    }

    }

    /*********************************************************************

    函数名称:encrypt

    函数作用:加密解密字符串

    使用方法:

    加密 :encrypt('str','E','nowamagic');

    解密 :encrypt('被加密过的字符串','D','nowamagic');

    参数说明:

    $string :需要加密解密的字符串

    $operation:判断是加密还是解密:E:加密 D:解密

    $key :加密的钥匙(密匙);

    *********************************************************************/

    function encrypt($string,$operation,$key='')

    {

    $key=md5($key);

    $key_length=strlen($key);

    $string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string;

    $string_length=strlen($string);

    $rndkey=$box=array();

    $result='';

    for($i=0;$i<=255;$i++)

    {

    $rndkey[$i]=ord($key[$i%$key_length]);

    $box[$i]=$i;

    }

    for($j=$i=0;$i<256;$i++)

    {

    $j=($j+$box[$i]+$rndkey[$i])%256;

    $tmp=$box[$i];

    $box[$i]=$box[$j];

    $box[$j]=$tmp;

    }

    for($a=$j=$i=0;$i

    {

    $a=($a+1)%256;

    $j=($j+$box[$a])%256;

    $tmp=$box[$a];

    $box[$a]=$box[$j];

    $box[$j]=$tmp;

    $result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));

    }

    if($operation=='D')

    {

    if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8))

    {

    return substr($result,8);

    }

    else

    {

    return'';

    }

    }

    else

    {

    return str_replace('=','',base64_encode($result));

    }

    }

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • $hashed_password = password_hash('mypassword',PASSWORD_BCRYPT); var_dump(password_verify ('...我们一般习惯性的使用MD5方法进行用户密码的加密处理,但是常见的Md5方法非常容易被一些大型解密网站破解;PHP提供...
    $hashed_password = password_hash('mypassword',PASSWORD_BCRYPT);
    var_dump(password_verify ('mypassword', $hashed_password.''));
    #结果true

    我们一般习惯性的使用MD5方法进行用户密码的加密处理,但是常见的Md5方法非常容易被一些大型解密网站破解;
    PHP提供了 'password_hash()' 函数可以生产更加安全的密码;
    password_hash一共支持三个参数的传入

    password_hash ( string $password , int $algo [, array $options ] )
    

     1:用户的明文密码;

    2:加密算法 (PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I);


            PASSWORD_BCRYPT 支持的选项:

     1. salt(string) - 手动提供散列密码的盐值(salt)。这将避免自动生成盐值(salt)。
          省略此值后,password_hash() 会为每个密码散列自动生成随机的盐值。这种操作是有意的模式。
          盐值(salt)选项从 PHP 7.0.0 开始被废弃(deprecated)了。 现在最好选择简单的使用默认产生的盐值。
    2. cost (integer) - 代表算法使用的 cost。 省略时,默认值是 10。 这个 cost 是个不错的底线,但也许可以根据自己硬件的情况,加大这个值

     

            PASSWORD_ARGON2I 支持的选项:

        memory_cost (integer) - 计算 Argon2 散列时的最大内存(单位:字节 byte)。默认值: PASSWORD_ARGON2_DEFAULT_MEMORY_COST。
        time_cost (integer) - 计算 Argon2 散列时最多的时间。默认值: PASSWORD_ARGON2_DEFAULT_TIME_COST。
        threads (integer) - 计算 Argon2 散列时最多的线程数。默认值: PASSWORD_ARGON2_DEFAULT_THREADS。
    

     

    3.一个包含有选项的关联数组 目前支持两个选项:salt (盐值) cost(用来指明算法递归的层数);

    返回值:
    返回散列后的密码,失败的时候返回False;
    其中返回的密码中包含了使用的(算法 cost 盐值) 所以我们可以不用存储盐值和算法的信息;
    使用password_verify()可以直接进行验证;

     

    使用案例:

    $options = [
      'cost' => 11,
        'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
     ];
    password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
    输出:$2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F.

    验证散列是否和密码匹配 password_verify()
    bool password_verify ( string $password , string $hash )
    参数1:传入用户密码 参数2:传入用户的哈希值

    案例:

    $hashed_password = password_hash('mypassword',PASSWORD_BCRYPT);
    var_dump(password_verify ('mypassword', $hashed_password.''));
    

     

    PHP官网解释:http://php.net/manual/zh/faq.passwords.php

          http://php.net/manual/zh/function.password-hash.php



     

     

    转载于:https://www.cnblogs.com/LiChen-789/p/10157411.html

    展开全文
  • 对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法.非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个...对称加密函数openssl...

    对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法.

    非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个负责解密.

    对称加密在性能上要优于非对称加密, 但是安全性低于非对称加密.

    PHP 7.1 之后的对称加密和非对称加密都需要借助 openssl 扩展实现. mcrypt 库已经被移除.

    对称加密函数

    openssl_get_cipher_methods() : 返回 openssl 支持的所有加密方式.
    openssl_encrypt($data, $method, $key, $options = 0, $iv = '') : 以指定方式 method 和密钥 key 加密 data, 返回 false 或加密后的数据.

    • data : 明文
    • method : 加密算法
    • key : 密钥
    • options :
      • 0 : 自动对明文进行 padding, 返回的数据经过 base64 编码.
      • 1 : OPENSSL_RAW_DATA, 自动对明文进行 padding, 但返回的结果未经过 base64 编码.
      • 2 : OPENSSL_ZERO_PADDING, 自动对明文进行 0 填充, 返回的结果经过 base64 编码. 但是, openssl 不推荐 0 填充的方式, 即使选择此项也不会自动进行 padding, 仍需手动 padding.
    • iv : 非空的初始化向量, 不使用此项会抛出一个警告. 如果未进行手动填充, 则返回加密失败.

    openssl_decrypt($data, $method, $key, $options = 0, $iv = '') : 解密数据.
    openssl_cipher_iv_length($method) : 获取 method 要求的初始化向量的长度.
    openssl_random_pseudo_bytes($length) : 生成指定长度的伪随机字符串.
    hash_mac($method, $data, $key, $raw_out) : 生成带有密钥的哈希值.

    • method : 加密算法
    • data : 明文
    • key : 密钥
    • raw_output :
      • TRUE : 输出原始二进制数据
      • FALSE : 输出长度固定的小写 16 进制字符串

    主流的对称加密方式有 DES, AES. 这两种加密方式都属于分组加密, 先将明文分成多个等长的模块 ( block ), 然后进行加密.

    DES 加密

    DES 加密的密钥长度为 64 bit, 实际应用中有效使用的是 56 位, 剩余 8 位作为奇偶校验位. 如果密钥长度不足 8 个字节, 将会使用 0 补充到 8 个字节. 如密钥为 "12345", 其加密后的密文与密钥 "12345000" 加密后的密文相同. 明文按 64 bit ( UTF-8 下为 8 个字节长度 ) 进行分组, 每 64 位分成一组 ( 最后一组不足 64 位的需要填充数据 ), 分组后的明文组和密钥按位替代或交换的方法形成密文组.

    class DES
    {
        private $method = 'DES-CBC';
        private $key;
    
        public function __construct($key)
        {
            // 密钥长度不能超过64bit(UTF-8下为8个字符长度),超过64bit不会影响程序运行,但有效使用的部分只有64bit,多余部分无效,可通过openssl_error_string()查看错误提示
            $this->key = $key;
        }
    
        public function encrypt($plaintext)
        {
            // 生成加密所需的初始化向量, 加密时缺失iv会抛出一个警告
            $ivlen = openssl_cipher_iv_length($this->method);
            $iv = openssl_random_pseudo_bytes($ivlen);
    
            // 按64bit一组填充明文
            //$plaintext = $this->padding($plaintext);
            // 加密数据. 如果options参数为0, 则不再需要上述的填充操作. 如果options参数为1, 也不需要上述的填充操作, 但是返回的密文未经过base64编码. 如果options参数为2, 虽然PHP说明是自动0填充, 但实际未进行填充, 必须需要上述的填充操作进行手动填充. 上述手动填充的结果和options为0和1是自动填充的结果相同.
            $ciphertext = openssl_encrypt($plaintext, $this->method, $this->key, 1, $iv);
            // 生成hash
            $hash = hash_hmac('sha256', $ciphertext, $this->key, false);
    
            return base64_encode($iv . $hash . $ciphertext);
    
        }
    
        public function decrypt($ciphertext)
        {
            $ciphertext = base64_decode($ciphertext);
            // 从密文中获取iv
            $ivlen = openssl_cipher_iv_length($this->method);
            $iv = substr($ciphertext, 0, $ivlen);
            // 从密文中获取hash
            $hash = substr($ciphertext, $ivlen, 64);
            // 获取原始密文
            $ciphertext = substr($ciphertext, $ivlen + 64);
            // hash校验
            if(hash_equals($hash, hash_hmac('sha256', $ciphertext, $this->key, false)))
            {
                // 解密数据
                $plaintext = openssl_decrypt($ciphertext, $this->method, $this->key, 1, $iv) ?? false;
                // 去除填充数据. 加密时进行了填充才需要去填充
                $plaintext = $plaintext? $this->unpadding($plaintext) : false;
    
                return $plaintext;
            }
    
            return '解密失败';
        }
    
        // 按64bit一组填充数据
        private function padding($plaintext)
        {
            $padding = 8 - (strlen($plaintext)%8);
            $chr = chr($padding);
    
            return $plaintext . str_repeat($chr, $padding);
        }
    
        private function unpadding($ciphertext)
        {
            $chr = substr($ciphertext, -1);
            $padding = ord($chr);
    
            if($padding > strlen($ciphertext))
            {
                return false;
            }
            if(strspn($ciphertext, $chr, -1 * $padding, $padding) !== $padding)
            {
                return false;
            }
    
            return substr($ciphertext, 0, -1 * $padding);
        }
    }

    AES 加密

    AES 加密的分组长度是 128 位, 即每个分组为 16 个字节 ( 每个字节 8 位 ). 密钥的长度根据加密方式的不同可以是 128 位, 192 位, 256 位. 与 DES 加密一样. 密钥长度超过指定长度时, 超出部分无效. 密钥长度不足时, 会自动以`0`补充到指定长度.

    507eea86c52c130b30cf5f96cbd3ea6c.png
    class AES
    {
        private $key;
        private $method = 'aes-128-cbc';
    
        public function __construct($key)
        {
            // 是否启用了openssl扩展
            extension_loaded('openssl') or die('未启用 OPENSSL 扩展');
            $this->key = $key;
        }
    
        public function encrypt($plaintext)
        {
            if(!in_array($this->method, openssl_get_cipher_methods()))
            {
                die('不支持该加密算法!');
            }
           // options为1, 不需要手动填充
            //$plaintext = $this->padding($plaintext);
            // 获取加密算法要求的初始化向量的长度
            $ivlen = openssl_cipher_iv_length($this->method);
            // 生成对应长度的初始化向量. aes-128模式下iv长度是16个字节, 也可以自由指定.
            $iv = openssl_random_pseudo_bytes($ivlen);
            // 加密数据
            $ciphertext = openssl_encrypt($plaintext, $this->method, $this->key, 1, $iv);
            $hmac = hash_hmac('sha256', $ciphertext, $this->key, false);
    
            return base64_encode($iv . $hmac . $ciphertext);
        }
    
        public function decrypt($ciphertext)
        {
            $ciphertext = base64_decode($ciphertext);
            $ivlen = openssl_cipher_iv_length($this->method);
            $iv = substr($ciphertext, 0, $ivlen);
            $hmac = substr($ciphertext, $ivlen, 64);
            $ciphertext = substr($ciphertext, $ivlen + 64);
            $verifyHmac = hash_hmac('sha256', $ciphertext, $this->key, false);
            if(hash_equals($hmac, $verifyHmac))
            {
                $plaintext = openssl_decrypt($ciphertext, $this->method, $this->key, 1, $iv)??false;
             // 加密时未手动填充, 不需要去填充
                //if($plaintext)
                //{
                //    $plaintext = $this->unpadding($plaintext);
                //    echo $plaintext;
                //}
    
                return $plaintext;
            }else
            {
                die('数据被修改!');
            }
        }
    
        private function padding(string $data) : string
        {
            $padding = 16 - (strlen($data) % 16);
            $chr = chr($padding);
            return $data . str_repeat($chr, $padding);
        }
    
        private function unpadding($ciphertext)
        {
            $chr = substr($ciphertext, -1);
            $padding = ord($chr);
    
            if($padding > strlen($ciphertext))
            {
                return false;
            }
    
            if(strspn($ciphertext, $chr, -1 * $padding, $padding) !== $padding)
            {
                return false;
            }
    
            return substr($ciphertext, 0, -1 * $padding);
        }
    }
    PHP进阶架构师>>>视频、面试文档免费获取docs.qq.com
    565ce4169e983b5086b7212ab8a7f10f.png

    非对称加密函数

    $res = openssl_pkey_new([array $config]) : 生成一个新的私钥和公钥对. 通过配置数组, 可以微调密钥的生成.

    • digest_alg : 摘要或签名哈希算法.
    • private_key_bits : 指定生成的私钥的长度.
    • private_key_type : 指定生成私钥的算法. 默认 OPENSSL_KEYTYPE_RSA, 可指定 OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH, OPENSSL_KEYTYPE_RSA, OPENSSL_KEYTYPE_EC.
    • config : 自定义 openssl.conf 文件的路径.

    openssl_pkey_free($res) : 释放有 openssl_pkey_new() 创建的私钥.
    openssl_get_md_methods() : 获取可用的摘要算法.
    openssl_pkey_export_to_file($res, $outfilename) : 将 ASCII 格式 ( PEM 编码 ) 的密钥导出到文件中. 使用相对路径时, 是相对服务器目录, 而非当前所在目录.
    openssl_pkey_export($res, &$out) : 提取 PEM 格式私钥字符串.
    openssl_pkey_get_details($res) : 返回包含密钥详情的数组.
    openssl_get_privatekey($key) : 获取私钥. key 是一个 PEM 格式的文件或一个 PEM 格式的私钥.
    openssl_get_publickey($certificate) : 获取公钥. certificate 是一个 X.509 证书资源或一个 PEM 格式的文件或一个 PEM 格式的公钥.
    openssl_private_encrypt($data, &$crypted, $privKey [, $padding = OPENSSL_PKCS1_PADDING]) : 使用私钥加密数据, 并保存到 crypted . 其中填充模式为 OPENSSL_PKCS1_PADDING 时, 如果明文长度不够, 加密时会在明文中随机填充数据. 为 OPENSSL_NO_PADDING 时, 如果明文长度不够, 会在明文的头部填充 0 .
    openssl_public_decrypt($crypted, &$decrypted, $pubKey [, $padding]) : 使用公钥解密数据, 并保存到 decrypted .
    openssl_public_encrypt($data, &$crypted, $pubKey [, $padding]) : 使用公钥加密数据, 并保存到 crypted .
    openssl_private_decrypt($crypted, &$decrypted, $privKey [, $padding]) : 使用私钥解密数据, 并保存到 decrypted .

    非对称加密

    RSA 也是一种分组加密方式, 但明文的分组长度根据选择的填充方式的不同而不同.

    class RSA
    {
        private $private_key; // 私钥
        private $public_key; // 公钥
        private $private_res; // 私钥资源
        private $public_res; // 公钥资源
    
        public function __construct()
        {
            extension_loaded('openssl') or die('未加载 openssl');
            // 生成新的公钥和私钥对资源
            $config = [
                'digest_alg' => 'sha256',
                'private_key_bits' => 1204,
                'private_key_type' => OPENSSL_KEYTYPE_RSA
            ];
            $res = openssl_pkey_new($config);
            if(!$res)
            {
                die('生成密钥对失败');
            }
    
            // 获取公钥, 生成公钥资源
            $this->public_key = openssl_pkey_get_details($res)['key'];
            $this->public_res = openssl_pkey_get_public($this->public_key);
    
            // 获取私钥, 生成私钥资源
            openssl_pkey_export($res, $this->private_key);
            $this->private_res = openssl_pkey_get_private($this->private_key);
    
            openssl_free_key($res);
        }
    
        // 加密
        public function encrypt($plaintext)
        {
            $ciphertext = null;
            openssl_public_encrypt($plaintext, $ciphertext, $this->public_res);
            return $ciphertext;
        }
    
        // 解密
        public function decrypt($ciphertext)
        {
            $plaintext = null;
            openssl_private_decrypt($ciphertext, $plaintext, $this->private_res);
            return $plaintext;
        }
    }

    在传输重要信息时, 一般会采用对称加密和非对称加密相结合的方式, 而非使用单一加密方式. 一般先通过 AES 加密数据, 然后通过 RSA 加密 AES 密钥, 然后将加密后的密钥和数据一起发送. 接收方接收到数据后, 先解密 AES 密钥, 然后使用解密后的密钥解密数据.

    以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要

    PHP进阶架构师>>>视频、面试文档免费获取docs.qq.com
    565ce4169e983b5086b7212ab8a7f10f.png

    或 者关注咱们下面的知乎专栏

    PHP架构师圈子zhuanlan.zhihu.com
    9597a624e5c7207e193d3cc4ec7c6d95.png
    展开全文
  • 对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法. 非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个负责...对称加密函数 o...
  • 对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法.非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个...对称加密函数openssl...
  • :小弟今日闲暇时间用GO语言简单的封装了几个加密函数,包括对称加密函数DES(虽然被破解很少用,但是可以作为了解),三重DES加密,AES的CBC和CTR模式(对称加密中常使用,推荐使用),非对称加密中的RSA加密解密...
  • 1.对称加密 对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读...
  • 4.Symmetric Algorithms:对称加密 对称加密的特征: 对称加密就是加密解密双方使用同一个密钥; 将数据切成块,然后再加密; 目前对称加密的方式有两种: ECB:Electronic CodeBook,each block is encrypted as...
  • 1、对称加密对称加密,是指在加密和解密时使用同一个秘钥。对称加密2、非对称加密...3、RSA:非对称加密鼻祖○ RSA 原理① 找出质数 :P = 3, Q = 11② 计算公共模数:N = P * Q = 33③ 欧拉函数:φ(N) = (P-1)(Q-...
  • 哈希函数又称为单向散列函数,任意长度经过哈希函数变成一个固定的值,且具有不可逆性。输入相同,输出一定相同,不同的输入数据想要获得相同的输出很难,概率很低。 可用作判断数据的完整性...对称机密算法:使用...
  • 一、PK 密钥使用方式:  对称加密:使用对称方式,使用同一个密钥进行加密与解密,密钥必须保密  非对称加密:使用非对称方式,使用两个密钥... 非对称加密:是使用数学函数进行变换的。 性能:  对称加
  • OpenSSL中对称加密算法DES常用函数使用举例

    万次阅读 热门讨论 2015-01-11 16:09:17
    OpenSSL中对称加密算法DES常用函数使用举例!
  • 疫情期间在家休息几天后,在头条偶读一片关于https中使用的什么加密方式的文章,由于知识模糊不清,特用这篇文章整理...其中f1和f2是两个加密函数(常见的“对称密钥”加密算法主要有DES、3DES(TripleDES)、AES...
  • * 对称加密算法在加密和解密时使用的是同一个秘钥;而非对称加密算法需要两个密钥来进行加密和解密, * 这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。 */ class AES { //...
  • 平时在工作中一直有使用到对称加密与非对称加密算法,以前一直是拿来就用,没有仔细想过里面的实现原理。今天突然有兴趣和时间研究下。 1、什么是对称加密算法? 加密和解密都使用相同密钥的算法。 公式:C=E(P,e...
  • HEX() 和 UNHEX() 函数 HEX():将一个字符串或数字转换为十六进制格式的字符串 UNHEX():将十六进制格式的字符串转化为原来的格式 加密AES_ENCRYPT(‘content’,‘secret’) INSERT INTO user(`password`) VALUES ...
  • 例如,我们常用的WinZIP和WinRAR对压缩包的加密和解密,就是使用对称加密算法:从程序的角度看,所谓加密,就是这样一个函数,它接收密码和明文,然后输出密文:secret = encrypt(key, message);而解密则相反,它...
  • 代码如下:–SQLSERVER中的加密函数 2013-7-11ENCRYPTBYASYMKEY() –非对称密钥ENCRYPTBYCERT() –证书加密ENCRYPTBYKEY() –对称密钥ENCRYPTBYPASSPHRASE() –通行短语(PassPhrase)加密 ——————————...
  • 1.对称加密(私钥加密) 私钥加密算法使用单个私钥来加密和解密数据。由于具有密钥的任意一方都可以使用该密钥解密数据,因此必须保护密钥不被未经授权的代理得到。私钥加密又称为对称加密,因为同一密钥既用于加密...
  • 跨平台C++ 对称加密解密函数

    千次阅读 2011-05-20 17:38:00
    void Encrypt(unsigned char* pdata,int len,unsigned long key0,unsigned long key1) { union sDWORD { unsigned long ldata; unsigned char b[4]; }; union sWORD { short a;... unsigned
  • 散列函数 或散列算法,又称哈希函数,英语:Hash Function)是一种从任何一种...对称加密 指加密和解密使用相同密钥的加密算法。 常用算法有:DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES 非对称加密 加密和解密...
  • 将php的openssl扩展中的非对称加密函数封装成一个Rsa类。 需要注意的是,在windows上,需要打开openssl的配置文件,请参照官方的openssl扩展安装文档。 在windows上安装openssl扩展 1、将php路径下的两个库文件...
  • 对称加密和非对称加密解密技术

    千次阅读 2015-01-26 23:38:06
     百度百科解释:所谓数据加密(Data Encryption)技术是指将一个信息(或称明文,plain text)经过加密钥匙(Encryption key)及加密函数转换,变成无意义的密文(cipher text),而接收方则将此密文经过解密函数、...
  • 对称加密解密通用类库函数 using System;using System.IO;using System.Text;using System.Security.Cryptography;namespace Common{ /// /// 加密解密通用类库函数 ///Copyright (C), 2004, kwklover(邝伟科) /...
  • 对称加密(4).NET非对称加密实践 非对称加密在理论上似乎比...当使用一个非对称加密类创建一个该类的实例的时候,构造函数会生成一个“公钥/私钥”对。我们可以选择是否保存该密钥和保存的方式。 先从代码清单6...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,039
精华内容 415
关键字:

对称加密函数