php 加密算法+接口安全技术

一、加密算法

1、散列加密(不可逆,md5、sha1、sha256)
1.1 md5 (长度16或32字节)
  $str = '203fpidf02lvj!!_@#_!';

        $md5_16 = md5($str,true); // 二进制字符

        echo $md5_16.'<br>';

        $md5_32 = md5($str);

        echo $md5_32.PHP_EOL;

结果:
在这里插入图片描述

1.2 sha1 (长度40字节)
		$str = '203fpid';

        $sha1 = sha1($str);

        echo $sha1.'<br>';

结果:
在这里插入图片描述

1.3 sha256 (长度64)
$str = '203fpidf02lvj!!_@#_!';

        $sha256 = hash('sha256',$str);

        echo $sha256.'<br>';

结果:
在这里插入图片描述

1.4 带秘钥的sha256 (长度64)
$str = '203fpidf02lvj!!_@#_!';

 $sha256 = hash_hmac('sha256',$str,'kjqfiuh');

echo $sha256.'<br>';
2、非对称加密(可逆,DES、3DES、AES)
2.1 AES
 function randstr($length) {

            $char_set = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'));
            shuffle($char_set);
            return implode('', array_slice($char_set, 0, $length));
        }

        $plaintext = "message to be encrypted";
        $cipher = "aes-128-cbc";
        $key = randstr(16);

        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt($plaintext, $cipher, $key, 0, $iv);

        echo $ciphertext.'<br>';
        $decrypt = openssl_decrypt($ciphertext,$cipher,$key,0,$iv);

        echo $iv.'<br>';
        echo $tag.'<br>';
        echo $decrypt;

结果:
在这里插入图片描述

2.2 DES

function randstr($length) {

        $char_set = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'));
        shuffle($char_set);
        return implode('', array_slice($char_set, 0, $length));
    }

    $plaintext = "message to be encrypted";
    $cipher = "DES-CBC";
    $key = randstr(16);

    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt($plaintext, $cipher, $key, 0, $iv);

    echo $ciphertext.'<br>';
    $decrypt = openssl_decrypt($ciphertext,$cipher,$key,0,$iv);

    echo $iv.'<br>';
    echo $decrypt;

在这里插入图片描述

2.3 3DES
function randstr($length) {

            $char_set = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'));
            shuffle($char_set);
            return implode('', array_slice($char_set, 0, $length));
        }


        $plaintext = "message to be encrypted";
        $cipher = "des-ede3-cbc";
        $key = randstr(16);

        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt($plaintext, $cipher, $key, 0, $iv);

        echo $ciphertext.'<br>';
        $decrypt = openssl_decrypt($ciphertext,$cipher,$key,0,$iv);

        echo $iv.'<br>';
        echo $decrypt;

结果:
在这里插入图片描述

3、对称加密(可逆,RSA、DSA)
3.1 RSA
3.1.1 openssl生成密钥对
openssl genrsa -out private_key.pem 2048 // 私钥
openssl rsa -in private_key.pem -pubout -out public_key.pem // 公钥

3.1.2 加解密
// 私钥文件,如果在文件中的可以通过file_get_contents获取
$private = '-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwcyzxL6GGMavrQBlH89Czvq16n8VukM53wb3+LHV6tBTbJTy(略)
-----END RSA PRIVATE KEY-----';

// 公钥文件,如果在文件中的可以通过file_get_contents获取
$public = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwcyzxL6GGMavrQBlH89C(略)
-----END PUBLIC KEY-----';

// 根据私钥文件获取私钥
$privateKey = openssl_pkey_get_private($private);

// 根据公钥文件获取公钥
$publicKey = openssl_pkey_get_public($public); 

// 原始数据
$content = ['name'=>'张三','age'=>18];

// 私钥加密
openssl_private_encrypt(json_encode($content),$encrypted,$privateKey);

// 非必须,可以通过base64_encode编码二进制字符串
$encrypted = base64_encode($encrypted);

// 非必须,可以通过base64_decode解码二进制字符串
$decrypted = base64_decode($encrypted );

// 公钥解密
openssl_public_decrypt($encrypted,$decrypted,$publicKey);

// 打印结果
print_r(json_decode($decrypted,true));

结果:
在这里插入图片描述

3.2 DSA

DSA常用于签名,没有找到php版本代码

二、接口安全技术

1、token

// 加密
$sign = md5(md5( 用户id + 时间戳 + 随机字符串) + $secretKey) // secret 保证的算法的安全性
$auth_token = base64_encode(用户id + 时间戳 + 随机字符串 + $sign);

// 解密
通过验证 md5(md5(用户id + 时间戳 + 随机字符串 + $secretKey)) == $sign 验证签名是否正确,
时间戳可以用来验证时效性

2、code实现接口只能访问一次

$code = md5(时间戳 + substr(uniqid(),7) + 随机字符串);存储在redis中,设置有效期(比如5分钟),使用后删除,实现单次访问

3、接口IP限流 (1分钟不能超过10次)

redis设置一个key :接口名+ip => 访问次数 设置有效期1分钟,1分钟后消失,每次ip访问接口,次数+1,如果总次数>10,报出异常

4、JWT
// 随机字符串(以为uniqid生成的唯一id基于微妙,有存在重复的可能性,增加随机字符串保证最后的唯一字符串的唯一性)
function randstr($len)
{
    $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';

    return substr(str_shuffle($str),0,$len);
}

// 生成随机字符串
$randstr = randstr(6);

// 签名密钥(盐)
$secret = 'school';

$header = [
    'type' => 'jwt',
    'alg' => 'sha256'
];

$payload = [
    'iss' => 'school', // jwt发布者
    'sub' => 'school', // jwt订阅者
    'aud' => '1001', // jwt用户
    'exp' => '1641784631', // jwt有效期截至时间戳
    'nbf' => '1641179831', // jwt有效期开始时间戳
    'iat' => '1641266232', // jwt发布时间戳
    'jti' => md5(time() . uniqid() . $randstr) // 唯一字符串,可用于不允许重复请求的情况
];

$header_encode = base64_encode(json_encode($header));
$payload_encode = base64_encode(json_encode($payload));
$sign = hash_hmac('sha256',$header_encode . $payload_encode . $secret,'');
$token = $header_encode.'.'. $payload_encode .'.'. $sign;
echo $token.PHP_EOL;
// 验证签名
$arr_token = explode('.',$token);

if (hash_hmac('sha256',$arr_token [0] . $arr_token [1] . $secret,'') == $arr[2]) {
    echo '签名正确';
} else {

    echo '签名错误';
}
// 结果
eyJ0eXBlIjoiand0IiwiYWxnIjoic2hhMjU2In0=.eyJpc3MiOiJzY2hvb2wiLCJzdWIiOiJzY2hvb2wiLCJhdWQiOiIxMDAxIiwiZXhwIjoiMTY0MTc4NDYzMSIsIm5iZiI6IjE2NDExNzk4MzEiLCJpYXQiOiIxNjQxMjY2MjMyIiwiand0aSI6ImMyZmExZTM2NmM1MzQ3NTg4Y2JmZWUzMzVkMWU2MmNkIn0=.04127dcff6623c843fd26b8ef1623dde3e7416f2c9052614d405f1fd7460b213 
签名正确
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值