mcrypt_decrypt在PHP7.*已经被弃用,取而代之的是openssl_decrypt/encrypt,请参考:

PHP7.* AES的加密解密

AES加密算法

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

解释来源:http://baike.so.com/doc/6783134-6999702.html

参考:http://www.docin.com/p-572103142.html

上一篇 :

PHP 开发API接口签名验证

中我们说到了sign签名,sign其实是防篡改的一种方法,它将约定好的排序、位置、数组进行密钥加密生成sign对比。

是的,sign签名我们是能看到数据的,只是可以防止数据的篡改。而AES可以加密解密数据

AES通过约定好的密钥进行加密,通过约定好的密钥解密。

ECB加密模式(不推荐):

容易被攻击

<?php

/*
* 加密
*/ function encrypt($input, $key) {
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$input = pkcs5_pad($input, $size);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, hextobin($key), $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
return $data;
} function pkcs5_pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
} /*
* 解密
*/ function decrypt($sStr, $sKey) {
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, hextobin($sKey), base64_decode($sStr), MCRYPT_MODE_ECB);
$dec_s = strlen($decrypted);
$padding = ord($decrypted[$dec_s - 1]);
$decrypted = substr($decrypted, 0, -$padding);
return $decrypted;
} function hextobin($hexstr) {
$n = strlen($hexstr);
$sbin = "";
$i = 0;
while ($i < $n) {
$a = substr($hexstr, $i, 2);
$c = pack("H*", $a);
if ($i == 0) {
$sbin = $c;
} else {
$sbin.=$c;
}
$i+=2;
}
return $sbin;
} define('SECRETKEY', '3163213543213543052abc43edfedus');
//Warning: mcrypt_decrypt(): Key of size 9 not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported
//Warning: pack(): Type H: illegal hex digit s
//Warning: pack(): Type H: illegal hex digit u
# 加密
echo $endata= encrypt('Hello, world! ', SECRETKEY); # 解密
echo $dedata= decrypt($endata, SECRETKEY);

有没有注意到 代码中的注释:

Warning: mcrypt_decrypt(): Key of size 9 not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported
 Warning: pack(): Type H: illegal hex digit s
Warning: pack(): Type H: illegal hex digit u

因为加密的密钥有长度限制所以必须为16、24、32的长度才可以

pack() 16进制转换为二进制的时候,发现了key密钥中包含了“s,u” 字符,想想看,16进制最多到F,F以后的字符都是扯蛋

1111 = 8 + 4 + 2 + 1 = 15 =F
1110 = 8 + 4 + 2 + 0 = 14= E
1101 = 8 + 4 + 0 + 1 = 13= D
1100 = 8 + 4 + 0 + 0 = 12 =C
1011 = 8 + 0 + 2 + 1 = 11= B
1010 = 8 + 0 + 2 + 0 = 10 =A

所以生成使用密钥的时候,我们应该预先生成好16进制的密钥。

加密后:

4ihVrJk0acwmAF6td5emIkV9T6VnRHYZcW2BUw4CSUQ=

解密后:

Hello, world!

 CBC加密模式 (推荐……):

define('SECRETKEY', '12f862d21d3ceafba1b88e5f22960d55');

/**
* 加密方法
* @param string $str
* @return string
*/
function encrypt($str) {
//AES, 128 ECB模式加密数据
$str = addPKCS7Padding($str);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$encrypt_str = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, SECRETKEY, $str, MCRYPT_MODE_CBC, '0000000000000000');
return base64_encode($encrypt_str);
} /**
* 解密方法
* @param string $str
* @return string
*/
function decrypt($str) {
//AES, 128 CBC模式加密数据
$str = base64_decode($str);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$encrypt_str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, SECRETKEY, $str, MCRYPT_MODE_CBC, '0000000000000000');
$encrypt_str = stripPKSC7Padding($encrypt_str);
return $encrypt_str;
} /**
* 填充算法
* @param string $source
* @return string
*/
function addPKCS7Padding($source) {
$source = trim($source);
$block = mcrypt_get_block_size('rijndael-128', 'cbc');
$pad = $block - (strlen($source) % $block);
if ($pad <= $block) {
$char = chr($pad);
$source .= str_repeat($char, $pad);
}
return $source;
} /**
* 移去填充算法
* @param string $source
* @return string
*/
function stripPKSC7Padding($source) {
$char = substr($source, -1);
$num = ord($char);
$source = substr($source, 0, -$num);
return $source;
} /**
* 加密
*/
$string =encrypt('Hello, world!');
print_r($string);
echo '<hr>';
/**
* 解密
*/
$string=decrypt($string);
print_r($string);

打印效果:

tZOYOkwxFdkqP6chub5Q8SsH9igXPIKlCNmWxVBjFkM=
Hello, world!

使用PKCS5Padding/PKCS7Padding填充可以兼容多平台语言之间AES加密解密(PHP、Java、C……)

注意这里每次产生的密文是相同的,因为设置了初试向量iv为16位个数的“0”。要产生不同的密文就要使用变化的初试向量iv

define('SECRETKEY', '12f862d21d3ceafba1b88e5f22960d55');

/**
* 加密方法
* @param string $str
* @return string
*/
function encrypt($str) {
//AES, 128 ECB模式加密数据
$str = addPKCS7Padding($str);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
define('A', $iv);
$encrypt_str = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, SECRETKEY, $str, MCRYPT_MODE_CBC, $iv);
return base64_encode($encrypt_str);
} /**
* 解密方法
* @param string $str
* @return string
*/
function decrypt($str) {
//AES, 128 ECB模式加密数据
$str = base64_decode($str);
$encrypt_str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, SECRETKEY, $str, MCRYPT_MODE_CBC,A);
$encrypt_str = stripPKSC7Padding($encrypt_str);
return $encrypt_str;
} /**
* 填充算法
* @param string $source
* @return string
*/
function addPKCS7Padding($source) {
$source = trim($source);
$block = mcrypt_get_block_size('rijndael-128', 'cbc');
$pad = $block - (strlen($source) % $block);
if ($pad <= $block) {
$char = chr($pad);
$source .= str_repeat($char, $pad);
}
return $source;
} /**
* 移去填充算法
* @param string $source
* @return string
*/
function stripPKSC7Padding($source) {
$char = substr($source, -1);
$num = ord($char);
$source = substr($source, 0, -$num);
return $source;
} /**
* 加密
*/
$string =encrypt('Hello, world!');
print_r($string);
echo '<hr>';
/**
* 解密
*/
$string=decrypt($string);
print_r($string);

打印效果:

faxcY9iEj4Q+67l2Fd+k+URMp8Y4VVih/JeUSQbYuwKw3u8holL0mdG3Jg51mbPxDFlj76M3dU8jYt2nhtUhxA==
tVWCmXvNuOeuWYI6VoSplUtdq+yV66vDr22Bdja2uNVpaftNNU6jwQWth2DD4JxgaL1d3Atv8jZGsoSV6XLJWA==
PTjgu8kJ1B7LTm40IXEl6fPVTbQYuETPvjg2miQVVs1i/r+07pjGAfsL5JpSQKOROMX8B3mSiSu/YjubHffkYA==
Cb5WjMwb3wOpqCmUWEErPc9sfUEYYiMzvoosYoHdCFq1vh78batnXLbpjOavnCT0Y6y+4jq+fviTmY3plOAK8g==

结果都是:

Hello, world!

 注意: 这里面的密钥define('SECRETKEY', '12f862d21d3ceafba1b88e5f22960d55');

长度为32位,但在严格的AES中,加密的密钥必须与字符串算法长度一至,(MCRYPT_RIJNDAEL_128、MCRYPT_RIJNDAEL_192、MCRYPT_RIJNDAEL_256)

 bit 位    =   二进制数据
byte 字节 = bit
字母 = byte = bit

也就是128位/8=16字节=16字符

192位/8=24字节=24字符

256位/8=32字节=32字符


所以,上面的代码为了兼容其他Java、C等,密钥应该改为16位:

define('SECRETKEY', '12f862d21d3ceafb')

也可以直接生成一个32位的16进制密钥用于其他功能的加密(sign签名),通过hex2bin可以将32位的16进制字符串转换为16位二进制字符串

生成16进制随机码

$num="";
for($i=0;$i<32;$i++){
$num .=dechex(rand(0,15));
}
echo $num;
echo $screct_key = hex2bin($num);
echo strlen($screct_key);

打印:

9957a20d097485d608d9f090efe34b9a
�W� t�������K�
16

PHP AES的加密解密-----【弃用】的更多相关文章

  1. PHP AES的加密解密

    AES加密算法 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DE ...

  2. PHP7.* AES的加密解密

    之前写过一篇: PHP AES的加密解密-----[弃用] 使用的是php5.*之前的mcrypt_decrypt 函数,该函数已经在php7.1后弃用了,上马的是openssl的openssl_en ...

  3. Golang之AES/DES加密解密

    AES/DES加密/解密涉及4个概念:1. Block, 也叫分组, 相应加密/解密的算法. 2. BlockMode, 模式, 相应加密/解密的处理.3. InitalVectory, 初始向量4. ...

  4. 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  5. AES在线加密解密-附AES128,192,256,CBC,CFB,ECB,OFB,PCBC各种加密解密源码

    一.AES在线加密解密:AES 128/192/256位CBC/CFB/ECB/OFB/PCBC在线加密解密|在线工具|在线助手|在线生成|在线制作 http://www.it399.com/aes ...

  6. PHP 服务端 和 APP 客户端 实现 RSA+AES 双向加密解密

    目的:服务端和移动端双向加密解密 共有七个文件 其中包括三个类文件 lib_aes.php aes对称加密解密类 server_rsa_crypt.php 服务端RSA公钥私钥非对称加密解密类 cli ...

  7. AES对称加密解密类

    import java.io.UnsupportedEncodingException; import javax.crypto.Cipher; import javax.crypto.spec.Se ...

  8. .NET/android/java/iOS AES通用加密解密(修正安卓)

    移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如.NET和android或者iOS的打交道.为了让数据交互更安全,我们需要对数据进行加密传输.今天研究了一下,把几种语言的加密都 ...

  9. JAVA和PYTHON同时实现AES的加密解密操作---且生成的BASE62编码一致

    终于有机会生产JAVA的东东了. 有点兴奋. 花了一天搞完.. java(关键key及算法有缩减): package com.security; import javax.crypto.Cipher; ...

随机推荐

  1. Python——递归函数

    1.定义:在自己的函数,调用自己 2.递归的最大内存不能超过997层 import sys sys.setrecursionlimit(1000000)   可以达到电脑理论的最大次 import s ...

  2. Nginx安全相关配置和nginx.conf中文详解

    一.centos下redis安全相关 1.背景 在使用云服务器时,如果我们的redis关闭了protected-mode模式,被病毒攻击的可能会大大增加,因此我们使用redis时候,最好更改默认端口, ...

  3. saltstack之自动化运维

    引入 简介 saltstack是由thomas Hatch于2011年创建的一个开源项目,设计初衷是为了实现一个快速的远程执行系统. 早期运维人员会根据自己的生产环境来写特定脚本完成大量重复性工作,这 ...

  4. SQLSERVER 实现三元运算符

    三元运算符在很多种编程语言中都存在,那么在SQL Server中有没有呢? 很遗憾,SQL server中并没有这个功能,三元运算符是什么呢? 这是一段表达式:[条件 ? 满足返回值 : 不满足返回值 ...

  5. C# 中ref与out关键字区别

    ref 关键字通过引用传递的参数的内存地址,而不是值.简单点说就是在方法中对参数的任何改变都会改变调用方的基础参数中.代码举例: class RefExample { static void Meth ...

  6. STM32的IO口是如何配置为某个外设使用的 ---?

    @2019-03-01 [猜想] 使用片内外设功能: 首先将对应 IO 口配置为复用输出 其次是 IO 口对应的多个功能外设,哪个外设使能即将外设与 IO 口相连 [疑问] 若多个外设都使能,那么到底 ...

  7. 扩展CRT +扩展LUCAS

    再次感谢zyf2000超强的讲解. 扩展CRT其实就是爆推式子,然后一路合并,只是最后一个式子上我有点小疑惑,但整体还算好理解. #include<iostream> #include&l ...

  8. 川普和习G-20会面为缓和中美贸易战提供了很大的机会

    川普和习将于这周在Buenos Aires(阿根廷首都)会面,互相商讨虚弱经济全球化的最大威胁. 自从川普在今年七月第一次开始提高中国商品关税之后,对全球的投资者和逐渐削弱的经济活动来说,两位领导人可 ...

  9. python中xrange和range(转)

    说到序列,我们第一想到的是一组有序元素组成的集合.同时,每个元素都有唯一的下标作为索引. 在Python中,有许多内界的序列.包括元组tuple,列表list,字符串str等.上面提到的序列类型(li ...

  10. 深入理解JVM(4)——对象的创建和访问

    1.对象的创建 在语言层面上,创建对象(例如克隆,反序列化)通常仅仅是一个new关键字而已. 在虚拟机中,对象(文中讨论的对象限于普通 Java 对象,不包括数组和 Class 对象等)的创建过程如下 ...