php加密解密的使用

  • 一、项目说明
  • 二、项目分析
    • 1.js外部文件
    • 2.HTML容器构建
    • 3.layui前端验证
    • 4.php后端验证
      • 封装函数
      • 密码验证规则
      • strpos内置函数
  • 三、经典的核心加密函数
    • 1.Discuz!开发之核心加密解密函数
    • 2.常用简单加密解密函数

一、项目说明

在开发大屏时,需要在前端输入密码,以便认证用户的登录权限。但是本次的项目需求是,没有数据库存储密码,且希望每次密码都不相同,最好是动态密码。

二、项目分析

  • 没有数据库储存密码,意味着密码将以明文或密文的形式储存于php文件中。从安全性和保密性来说,不是很强。登录、验证、判断即可。
  • 动态密码,既能满足动态不断变换又能是通用规则,内部员工知晓即可的条件,就自有不断变换的时间了。

基于此,做了个简单的DEMO。输入年时间作为动态密码,在后端验证时,任意输入密码字符串,只要包含当前符合规则的联系数字即可。现在是2023年4月24日 18:05,生成的密码分为三种情况:

  1. 20231805,8位数字;
  2. 231805,6位数字;
  3. 1805,4位数字;

1.js外部文件

  <title>漏刻有时密码测试工具</title><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/functions.js"></script><!--layui封装库--><script src="js/layui/layui.js" charset="utf-8"></script><link rel="stylesheet" href="js/layui/css/layui.css">

2.HTML容器构建

<div class="layui-fluid" style="margin-top: 20px;"><form class="layui-form layui-form-pane" lay-filter="component-form-group"><div class="layui-card"><div class="layui-card-header" style="font-weight: bold;text-align: center;">漏刻有时密码测试工具</div><div class="layui-card-body" style="padding: 15px;"><div class="layui-form-item"><label class="layui-form-label">测试密码<span class="x-red">*</span></label><div class="layui-input-inline"><input type="password" id="password" name="password" autocomplete="off" lay-verify="password" class="layui-input"></div><div class="layui-form-mid layui-word-aux"><span id="passTips" class="x-red"></span></div></div><div class="layui-form-item"><label class="layui-form-label">密码明文<span class="x-red">*</span></label><div class="layui-input-inline"><input type="text" id="passshow" name="passshow" autocomplete="off" lay-verify="required" class="layui-input" readonly></div></div><div class="layui-form-item"><a class="layui-btn layui-btn-fluid layui-btn-normal" lay-filter="save" id="L_add" lay-submit=""><i class="layui-icon layui-icon-search"></i> 确定配置 </a></div></div></div></form>
</div>

3.layui前端验证

  //同步密码;$("#password").change(function(){var $pass= $("#password").val();$("#passshow").val($pass);})layui.use(['form'], function () {var $ = layui.jquery;var form = layui.form;//验证规则form.verify({password: [/(?=.*[0-9])(?=.*[a-zA-Z]).{6,30}/, '密码必须同时包含字母和数字且至少6位']});//监听提交;form.on('submit(save)', function () {$.ajax({type: "post",url: "indexDeal.php?act=annual",async: true,data: {pass: $('#password').val()},dataType: "json",success: function (res) {if (res.code == 1) {layer.msg(res.msg + "成功", {icon: 1, time: 1000}, function () {$("#passTips").html("您的密码为:"+res.pass);});}else{layer.msg(res.msg + "失败", {icon: 2, time: 1000}, function () {$("#passTips").html("您的密码为:"+res.pass);});}}});return false;});});

4.php后端验证

$act = $_GET['act'];
if ($act == 'annual') {//获取前端输入密码$pass = trim($_POST['pass']);$res['code'] = dynamicCode($pass, 2);$res['pass'] = $pass;$res['msg'] = "密码已验证:";die(json_encode($res));
}

封装函数

/*判断是否包含*/
function getCode($str, $server_pass)
{if (strpos($str, $server_pass) === FALSE) {return 0;} else {return 1;}
}

密码验证规则

/*动态密码*/
function dynamicCode($str, $type = '1')
{/*$server_pass* 默认获取系统的时间,即服务器的时间* 默认客户端时间和系统时间同步;* 返回0,代表验证失败;1,代表验证成功;*//*验证密码* 1,前端获取的字符串是否包含连续的$server_pass,仿密码锁原理,只要联系输对即可* */switch ($type) {case 1://8位数字密码$server_pass = date('YHi');//时间格式20232330,代表2023年23:30return getCode($str, $server_pass);break;case 2://六位密码$server_pass = date('yHi');//时间格式20232330,代表2023年23:30return getCode($str, $server_pass);break;case 3://四位密码$server_pass = date('Hi');//时间格式20232330,代表2023年23:30return getCode($str, $server_pass);break;default:return 0;}
}

strpos内置函数

定义和用法

strpos(string,find,start)

strpos() f函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。

相关函数:

  • strrpos() - 查找字符串在另一字符串中最后一次出现的位置(区分大小写)
  • stripos() -查找字符串在另一字符串中第一次出现的位置(不区分大小写)
  • strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写)

三、经典的核心加密函数

1.Discuz!开发之核心加密解密函数

Discuz!开发的使用异或运算进行加密和解密的函数,Discuz!所有产品都是用这个函数。Discuz!整合UCenter的同步登录中authcode()就扮演者重要的角色。在同步登录(从项目登录到UCenter)的过程中,authcode()把用户的登录信息进行加密,因为没有加密的数据在传递过程中容易被截取,会暴露了用户的信息,authcode()的作用就是给传递的数据提供加密保护作用。在数据到达终端(UCenter)时authcode()再把加密的数据进行反向解密,还原数据。

AuthCode动态密匙加解密并设置密文有效期,相同的明文会生成不同密文。

  • AuthCode的算法非常经典和使用,在实际使用的过程中必须设置$key,防止被截获予以破解;
  • 在使用get方式传递参数时,产生的+容易被当成空格处理,因此在接受参数的时候,需要予以替换解决。
<?php
/* 参数解释$string: 明文 或 密文$operation:DECODE表示解密,其它表示加密$key: 密匙$expiry:密文有效期*/
if(!function_exists('AuthCode'))
{function AuthCode($string, $operation='DECODE', $key='', $expiry=0){// 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙// 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。// 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方// 当此值为 0 时,则不产生随机密钥$cfg_auth_key = '';$ckey_length = 4;// 密匙$key = md5($key ? $key : $cfg_auth_key);// 密匙a会参与加解密$keya = md5(substr($key, 0, 16));// 密匙b会用来做数据完整性验证$keyb = md5(substr($key, 16, 16));// 密匙c用于变化生成的密文$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';// 参与运算的密匙$cryptkey = $keya.md5($keya.$keyc);$key_length = strlen($cryptkey);// 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),解密时会通过这个密匙验证数据完整性// 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确$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是三个数相加与256取余$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++){//在上面基础上再加1 然后和256取余$a = ($a + 1) % 256;$j = ($j + $box[$a]) % 256;//$j加$box[$a]的值 再和256取余$tmp = $box[$a];$box[$a] = $box[$j];$box[$j] = $tmp;// 从密匙簿得出密匙进行异或,再转成字符,加密和解决时($box[($box[$a] + $box[$j]) % 256])的值是不变的。$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));}if($operation == 'DECODE'){// substr($result, 0, 10) == 0 验证数据有效性// substr($result, 0, 10) - time() > 0 验证数据有效性// substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性// 验证数据有效性,请看未加密明文的格式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{// 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因// 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码return $keyc.str_replace('=', '', base64_encode($result));}}
}

2.常用简单加密解密函数

下面的加密解密函数是一段比较简单的算法,仅限于数字、字母和大小写,在对保密性要求不高的情形下,可以使用。

function lockAuth($tex, $key, $type = "encode")
{$chrArr = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','0', '1', '2', '3', '4', '5', '6', '7', '8', '9');if ($type == "decode") {if (strlen($tex) < 14) return false;$verity_str = substr($tex, 0, 8);$tex = substr($tex, 8);if ($verity_str != substr(md5($tex), 0, 8)) {//完整性验证失败return false;}}$key_b = $type == "decode" ? substr($tex, 0, 6) : $chrArr[rand() % 62] . $chrArr[rand() % 62] . $chrArr[rand() % 62] . $chrArr[rand() % 62] . $chrArr[rand() % 62] . $chrArr[rand() % 62];$rand_key = $key_b . $key;$rand_key = md5($rand_key);$tex = $type == "decode" ? base64_decode(substr($tex, 6)) : $tex;$texlen = strlen($tex);$reslutstr = "";for ($i = 0; $i < $texlen; $i++) {$reslutstr .= $tex{$i} ^ $rand_key{$i % 32};}//加密if ($type != "decode") {$reslutstr = trim($key_b . base64_encode($reslutstr), "==");$reslutstr = substr(md5($reslutstr), 0, 8) . $reslutstr;}return $reslutstr;
}

@漏刻有时

php动态密码和加密解密函数的使用(动态密码、Discuz核心函数AuthCode、任意输入密码验证)相关推荐

  1. 用户密码的加密解密操作(前端加密,后端解密)

    用户密码的加密解密操作 作者是个小菜狗,行文过程基本都基于自己理解,没有深入查阅文献,如有错误,还请大神指出 背景: 公司做的是一个某某平台的系统,包括前台和后台,作者刚毕业,刚开始试用,带我的师傅让 ...

  2. 凯撒密码的加密解密算法实现

    用C++实现凯撒密码的加密解密算法 在密码学中,恺撒密码(英语:Caesar cipher),或称恺撒加密.恺撒变换.变换加密,是一种最简单且最广为人知的加密技术. 它是一种替换加密的技术,明文中的所 ...

  3. 将 Shiro 作为应用的权限基础 五:密码的加密/解密在Spring中的应用

    2019独角兽企业重金招聘Python工程师标准>>> 考虑系统密码的安全,目前大多数系统都不会把密码以明文的形式存放到数据库中. 一把会采取以下几种方式对密码进行处理 密码的存储 ...

  4. pkcs1解密 springboot_使用springboot完成密码的加密解密

    现今对于大多数公司来说,信息安全工作尤为重要,就像京东,阿里巴巴这样的大公司来说,信息安全是最为重要的一个话题,举个简单的例子: 就像这样的密码公开化,很容易造成一定的信息的泄露.所以今天我们要讲的就 ...

  5. Web登录使用RSA对密码进行加密解密过程

    RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥.首先简单说一下RSA加密方式(借用知乎上面的理解,通俗易懂): ...

  6. 密码加密解密(三)——仿射密码设计

    代换密码算法的原理是使用替代法进行加密,就是将明文中的字符用其它字符替代后形成密文.例如,明文字母a.b.c.d,用D.E.F.G做对应替换后形成密文. 代换密码包括多种类型,如单表代换密码.多表代换 ...

  7. 压缩包密码如何加密解密

    压缩包文件该如何加密?有密码的情况下又该如何解密?忘记了密码该怎么办?下面分享一下方法: 压缩包加密方法: 选择需要加密的文件,右键点击文件,选择[添加到压缩文件] 然后在详细的设置界面中,我们找到[ ...

  8. 如何计算维吉尼亚密码?Java实现维吉尼亚密码的加密解密算法

    文章目录 如何计算维吉尼亚密码? Java实现加密算法 Java实现解密算法 参考博客 如何计算维吉尼亚密码? 计算维吉尼亚密码有2种方式,一种是根据密码表查找,另一种是手动计算方法. 1.密码表查找 ...

  9. 对数据库中的数据(用户名/密码)加密解密

    生成32位加密文: public static String md5Encode(String inStr) throws Exception {MessageDigest md5 = null;tr ...

最新文章

  1. slice,substr和substring的区别
  2. linux下Yum的$releasever和$basearch的取值
  3. 皮一皮:直男的拍摄水平...
  4. 嗅探(被动嗅探)与ARP欺骗(主动嗅探)详解
  5. python树形_Python处理树形数组
  6. 95-090-022-源码-bin脚本-CLI提交Job的时候加载插件
  7. PHP页面跳转几种实现方法
  8. SQL Server 数据库文件和文件组
  9. ArcMap通过空间校正工具转换BJ-54坐标系到WGS-84坐标系
  10. 《HarmonyOS开发 - 小凌派-RK2206开发笔记》第2章 源码编译与固件下载
  11. MySQL之查询关键字
  12. PhotoShop纸张大小
  13. 转一篇人生感悟,写的很好
  14. StatusBar用法
  15. 前端开发中需要用到的变换矩阵(2D游戏适用)
  16. 游戏图形测试软件,今日共有3款免费测试网络游戏(组图)
  17. python2和python3
  18. 史迪仔的原型_果果的故事之(史迪仔)
  19. 计算机主机打不开怎么解决办法,电脑打不开的解决方法步骤详解
  20. 华为发布敏捷交换机备战大数据

热门文章

  1. 流行的邮件系统--extmail
  2. 输入一个字符串,内有数字和非数字字符,例如:A123x456 17960? ,302tab5876,将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a1[1].
  3. 红米k40可以升级鸿蒙系统吗,红米k40哪个版本系统版本好
  4. java进行抽奖_简单实现java抽奖系统
  5. 中兴服务器远程,如何远程控制中兴支点操作系统远程桌面
  6. 餐讯头条丨2019中华小吃产业发展大会圆满落幕
  7. cpmp和pmp(cpmp和pmp哪个好考)
  8. 如何给DPDK开源社区提交补丁
  9. JS 倒计时展示小工具
  10. 深圳市龙岗职业技术学校录取分数线计算机,深圳各职校录取分数线