php解决aes(php解决高并发 面试)

发布时间:2022-11-16

本文目录一览:

  1. PHP对称加密-AES
  2. PHP 加密:AES & RSA
  3. PHP如何实现AES加解密
  4. 如何用php做AES加密解密,编码是UTF-8,跪谢求代码
  5. php AES加密对不上java的加密,请问如何实现?
  6. 前端JS AES加密 后端PHP AES加解密

PHP对称加密-AES

对称加解密算法中,当前最为安全的是 AES 加密算法(以前应该是是 DES 加密算法),PHP 提供了两个可以用于 AES 加密算法的函数簇: Mcrypt 和 OpenSSL 。 其中 Mcrypt 在 PHP 7.1.0 中被弃用(The Function Mycrypt is Deprecated),在 PHP 7.2.0 中被移除,所以即可起你应该使用 OpenSSL 来实现 AES 的数据加解密。 在一些场景下,我们不能保证两套通信系统都使用了相函数簇去实现加密算法,可能 siteA 使用了最新的 OpenSSL 来实现了 AES 加密,但作为第三方服务的 siteB 可能仍在使用 Mcrypt 算法,这就要求我们必须清楚 Mcrypt 同 OpenSSL 之间的差异,以便保证数据加解密的一致性。 下文中我们将分别使用 Mcrypt 和 OpenSSL 来实现 AES-128/192/256-CBC 加解密,二者同步加解密的要点为: 协同好以上两点,就可以让 Mcrypt 和 OpenSSL 之间一致性的对数据进行加解密。 AES 是当前最为常用的安全对称加密算法,关于对称加密这里就不在阐述了。 AES 有三种算法,主要是对数据块的大小存在区别:

  • AES-128:需要提供 16 位的密钥 key
  • AES-192:需要提供 24 位的密钥 key
  • AES-256:需要提供 32 位的密钥 key AES 是按数据块大小(128/192/256)对待加密内容进行分块处理的,会经常出现最后一段数据长度不足的场景,这时就需要填充数据长度到加密算法对应的数据块大小。 主要的填充算法有填充 NUL("0") 和 PKCS7,Mcrypt 默认使用的 NUL("0") 填充算法,当前已不被推荐,OpenSSL 则默认模式使用 PKCS7 对数据进行填充并对加密后的数据进行了 base64encode 编码,所以建议开发中使用 PKCS7 对待加密数据进行填充,已保证通用性(alipay sdk 中虽然使用了 Mcrypt 加密簇,但使用 PKCS7 算法对数据进行了填充,这样在一定程度上亲和了 OpenSSL 加密算法)。 Mcrypt 的默认填充算法。NUL 即为 Ascii 表的编号为 0 的元素,即空元素,转移字符是 "\0",PHP 的 pack 打包函数在 'a' 模式下就是以 NUL 字符对内容进行填充的,当然,使用 "\0" 手动拼接也是可以的。 OpenSSL的默认填充算法。下面我们给出 PKCS7 填充算法 PHP 的实现: 默认使用 NUL("\0") 自动对待加密数据进行填充以对齐加密算法数据块长度。 获取 mcrypt 支持的算法,这里我们只关注 AES 算法。 注意:mcrypt 虽然支持 AES 三种算法,但除 MCRYPT_RIJNDAEL_128 外, MCRYPT_RIJNDAEL_192/256 并未遵循 AES-192/256 标准进行加解密的算法,即如果你同其他系统通信(java/.net),使用 MCRYPT_RIJNDAEL_192/256 可能无法被其他严格按照 AES-192/256 标准的系统正确的数据解密。官方文档页面中也有人在 User Contributed Notes 中提及。这里给出如何使用 mcrpyt 做标注的 AES-128/192/256 加解密 即算法统一使用 MCRYPT_RIJNDAEL_128 ,并通过 key 的位数 来选定是以何种 AES 标准做的加密,iv 是建议添加且建议固定为16位(OpenSSL的 AES加密 iv 始终为 16 位,便于统一对齐),mode 选用的 CBC 模式。 mcrypt 在对数据进行加密处理时,如果发现数据长度与使用的加密算法的数据块长度未对齐,则会自动使用 "\0" 对待加密数据进行填充,但 "\0" 填充模式已不再被推荐,为了与其他系统有更好的兼容性,建议大家手动对数据进行 PKCS7 填充。 openssl 簇加密方法更为简单明确,mcrypt 还要将加密算法分为 cipher + mode 去指定,openssl 则只需要直接指定 method 为 AES-128-CBC,AES-192-CBC,AES-256-CBC 即可。且提供了三种数据处理模式,即 默认模式 0 / OPENSSL_RAW_DATA / OPENSSL_ZERO_PADDING 。 openssl 默认的数据填充方式是 PKCS7,为兼容 mcrpty 也提供处理 "0" 填充的数据的模式,具体为下: options 参数即为重要,它是兼容 mcrpty 算法的关键:
  • options = 0 : 默认模式,自动对明文进行 pkcs7 padding,且数据做 base64 编码处理。
  • options = 1 : OPENSSL_RAW_DATA,自动对明文进行 pkcs7 padding, 且数据未经 base64 编码处理。
  • options = 2 : OPENSSL_ZERO_PADDING,要求待加密的数据长度已按 "0" 填充与加密算法数据块长度对齐,即同 mcrpty 默认填充的方式一致,且对数据做 base64 编码处理。注意,此模式下 openssl 要求待加密数据已按 "0" 填充好,其并不会自动帮你填充数据,如果未填充对齐,则会报错。 故可以得出 mcrpty簇 与 openssl簇 的兼容条件如下: 建议将源码复制到本地运行,根据运行结果更好理解。
  1. 二者使用的何种填充算法。
  2. 二者对数据是否有 base64 编码要求。
  3. mcrypt 需固定使用 MCRYPT_RIJNDAEL_128,并通过调整 key 的长度 16, 24,32 来实现 ase-128/192/256 加密算法。

PHP 加密:AES & RSA

最近两年一直从事与金融相关项目的开发与维护。但是,关于 PHP 加密解密的最佳实践,网上没有人给出一个完美的总结。恰逢最近看了《图解密码技术》一书,对 PHP 加解密有了更深刻的认识。 为了避免各位看枯燥的文字理论,开篇我就把总结给出:

一、对称加密

对称加密的特点是加解密速度快,加密后的密文强度目前还没有硬解的可能性。但是,在未来随着计算机性能的提升有可能会出现被破解的可能性。 对称加密的缺点也很明显。对称加密的加密过程与解密过程使用的是同一把密钥。一旦泄漏密钥,加密就失去了任何意义。 根据《图解密码技术》一书的推荐,对称加密目前推荐使用 AES。在 PHP 当中要实现 AES 加解密,是使用 openssl 扩展来实现。所以,请确保你的 PHP 已经开启了 openssl 扩展。 可以通过如下方式检测: 或者如下方式检测: AES 的加密模式属于分组密码模式。所谓分组密码,是加密时把明文按照固定的长度分组,然后再进行加密。当然,细节之处很很多不同。AES 分组模式有多种:ECB、CBC、CFB、OFB、CTR 五种分组模式。目前优先推荐使用 CBC 模式。 如果使用 CBC 模式,那么在加密的时候,就需要一个前置的加密向量 IV。当初博主在使用 AES 来加密的时候,就很奇怪一个对称加密为何要这个向量。因为,在博主寒冰的潜意识里,对称加密只需要一个密钥就 Ok 了。没想到 AES 加密还有多种模式,而这个 CBC 模式恰恰就需要一个这样的向量值。关于这个向量大家可以在网上查阅相关的资料。这个东西非常重要,也非常好理解。 关于 PHP AES 加解密会用到的相关方法: AES 支持三种强度:128、192、256。128 位的强度最低,但是,加密解密速度较快。256 位强度最高,但是,加密解密速度最低。所以,大家根据自己系统的重要程度选择使用对应强度。通常普通的金融项目使用 192 位完整够用了。顶级的就用 256 位。其他的就用 128 位吧。

二、非对称加密

非对称加密是指公钥加密私钥解密,私钥加密公钥解密的算法。非对称加密的算法有很多。《图解密码技术》一书推荐使用 RSA 算法。它使用起来也非常简单。 要使用 RSA 算法。首先,我们必须生成一对公钥私钥。其实生成公钥私钥很简单。 在 Linux 系统,直接使用如下命令生成: 此命令会生 ~/.ssh/ 目录下生成两个文件:

  • id_rsa 是私钥
  • is_rsa.pub 是公钥 关于 PHP RSA 加解密会用到的相关方法: 以上就是关于在 PHP 项目开发中,我们使用的加密解密算法的一个总结。博主寒冰在总结过程中难免会有不足之处,还请大家指正!谢谢!

PHP如何实现AES加解密

AES(The Advanced Encryption Standard)是美国国家标准与技术研究所用于加密电子数据的规范。它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。本文展示了AES的概貌并解析了它使用的算法。包括一个完整的C#实现和加密.NET数据的举例。在读完本文后你将能用AES加密、测试 基于AES的软件并能在你的系统中使用AES加密。

如何用php做AES加密解密,编码是UTF-8,跪谢求代码

class CryptAES
{
    protected $cipher = MCRYPT_RIJNDAEL_128;
    protected $mode = MCRYPT_MODE_ECB;
    protected $pad_method = NULL;
    protected $secret_key = '';
    protected $iv = '';
    public function set_cipher($cipher)
    {
        $this->cipher = $cipher;
    }
    public function set_mode($mode)
    {
        $this->mode = $mode;
    }
    public function set_iv($iv)
    {
        $this->iv = $iv;
    }
    public function set_key($key)
    {
        $this->secret_key = $key;
    }
    public function require_pkcs5()
    {
        $this->pad_method = 'pkcs5';
    }
    protected function pad_or_unpad($str, $ext)
    {
        if (is_null($this->pad_method)) {
            return $str;
        } else {
            $func_name = __CLASS__ . '::' . $this->pad_method . '_' . $ext . 'pad';
            if (is_callable($func_name)) {
                $size = mcrypt_get_block_size($this->cipher, $this->mode);
                return call_user_func($func_name, $str, $size);
            }
        }
        return $str;
    }
    protected function pad($str)
    {
        return $this->pad_or_unpad($str, '');
    }
    protected function unpad($str)
    {
        return $this->pad_or_unpad($str, 'un');
    }
    public function encrypt($str)
    {
        $str = $this->pad($str);
        $td = mcrypt_module_open($this->cipher, '', $this->mode, '');
        if (empty($this->iv)) {
            $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        } else {
            $iv = $this->iv;
        }
        mcrypt_generic_init($td, $this->secret_key, $iv);
        $cyper_text = mcrypt_generic($td, $str);
        $rt = base64_encode($cyper_text);
        //$rt = bin2hex($cyper_text);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $rt;
    }
    public function decrypt($str)
    {
        $td = mcrypt_module_open($this->cipher, '', $this->mode, '');
        if (empty($this->iv)) {
            $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        } else {
            $iv = $this->iv;
        }
        mcrypt_generic_init($td, $this->secret_key, $iv);
        //$decrypted_text = mdecrypt_generic($td, self::hex2bin($str));
        $decrypted_text = mdecrypt_generic($td, base64_decode($str));
        $rt = $decrypted_text;
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return $this->unpad($rt);
    }
    public static function hex2bin($hexdata)
    {
        $bindata = '';
        $length = strlen($hexdata);
        for ($i = 0; $i < $length; $i += 2) {
            $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
        }
        return $bindata;
    }
    public static function pkcs5_pad($text, $blocksize)
    {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }
    public static function pkcs5_unpad($text)
    {
        $pad = ord($text{strlen($text) - 1});
        if ($pad > strlen($text)) return false;
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
        return substr($text, 0, -1 * $pad);
    }
}
/*$keyStr = 'UITN25LMUQC436IM';
$plainText = 'this is a string will be AES_Encrypt';
$aes = new CryptAES();
$aes->set_key($keyStr);
$aes->require_pkcs5();
$encText = $aes->encrypt($plainText);
$decString = $aes->decrypt($encText);
echo $encText,"\n",$decString;*/

php AES加密对不上java的加密,请问如何实现?

要注意特定的Padding实现跟算法的blockSize有关,这里php的blocksize是在php的aes加密前先对源字符串进行Padding,问题得到解决。

前端JS AES加密 后端PHP AES加解密

<!DOCTYPE html>
<html>
<head>
    <title>aes demo</title>
</head>
<body>
    <script type="text/javascript" src="./CryptoJS/aes.js"></script>
    <script type="text/javascript" src="./CryptoJS/pad-zeropadding.js"></script>
    <script type="text/javascript">
        text = 'did=12345dgversion=1';
        var key = '123454536f667445454d537973576562';
        key = CryptoJS.enc.Utf8.parse(key);
        var iv = "1234577290ABCDEF1264147890ACAE45";
        iv = CryptoJS.enc.Utf8.parse(iv);
        var encrypted = CryptoJS.AES.encrypt(text, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        }).toString()
        document.write(encrypted);
    </script>
</body>
</html>

后端

public function encrypt2($input = '')
{
    $pk = "123454536f667445454d537973576562";
    $iv = substr("1234577290ABCDEF1264147890ACAE45", 0, 16);
    // $t = 'T10515';
    $encrypted = (mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $pk, $input, MCRYPT_MODE_CBC, $iv));
    return base64_encode($encrypted);
}
public function decrypt2($encrypted)
{
    $pk = "123454536f667445454d537973576562";
    $iv = substr("1234577290ABCDEF1264147890ACAE45", 0, 16);
    // $t = 'T10515';
    // $encrypted = "b7y/JPJFNTfxNVR8H4NNtw==";
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $pk, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv);
}

可以推断, js 部分实际只使用了 iv 的 16 位长度 ps: js加密后默认会base64_encode 使用php解密需要base64_decode后才一致 所以使用js加密和php解密时候需要注意,php端要先base64_decode再解密,例: js加密的串是$t=b7y/JPJFNTfxNVR8H4NNtw== php需要

$password = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $pk, base64_decode($t), MCRYPT_MODE_CBC, $iv));

则$password才能正确解析出来 需要引入的两个js文件 ase.js

/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var this=this.extend();this.init.apply(this,arguments);return this},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>2]|=(e[k>>2]>>24-8*(k%4)<<24)>>>24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>2]=e[k>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>2]&=4294967295<<32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>2]>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>2]|=parseInt(a.substr(j,2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>2]>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<b;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this);a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a,e)).finalize(b)}}});var n=d.algo={};return d}(Math);

pad-zeropadding.js

/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
/**
 * Zero padding strategy.
 */
CryptoJS.pad.ZeroPadding = {
    pad: function (data, blockSize) {
        // Shortcut
        var blockSizeBytes = blockSize * 4;
        // Pad
        data.clamp();
        data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
    },
    unpad: function (data) {
        // Shortcut
        var dataWords = data.words;
        // Unpad
        var i = data.sigBytes - 1;
        while (!((dataWords[i >> 2] >> (24 - (i % 4) * 8)) & 0xff)) {
            i--;
        }
        data.sigBytes = i + 1;
    }
};