PHP对称加密(AES加密算法)与非对称加密(RSA加密算法)

更新时间: 2022-03-04 16:24:48 为了保证网络传输数据的安全性,涉及敏感数据的传输,最好对数据预先加密,然后再在网络上进行传输,同时,还要保证数据在另一端是可解密的,并且还必须要通过钥匙(公钥或私钥)才能解密,没有钥匙(公钥或私钥)的人即使是拿到了加密过的数据也无法解密。

PHP对称加密(AES加密算法)与非对称加密(RSA加密算法)详细讲解及php的实现

为了保证网络传输数据的安全性,涉及敏感数据的传输,最好对数据预先加密,然后再在网络上进行传输,同时,还要保证数据在另一端是可解密的,并且还必须要通过钥匙(公钥或私钥)才能解密,没有钥匙(公钥或私钥)的人即使是拿到了加密过的数据也无法解密。

设计签名验证的时候,一定要满足以下几点:

可变性:每次的签名必须是不一样的。

时效性:每次请求的时效性,过期作废。

唯一性:每次的签名是唯一的。

完整性:能够对传入数据进行验证,防止篡改。

单向散列加密

把任意长的输入串变化成固定长的输出串,并且由输出串难以得到输入串,这种方法称为单项散列加密。

这句话简单点就是加密后的字符串无法还原

应用场景

用于敏感数据,比如用户密码,请求参数,文件加密等

在单向加密算法中常用的算法有:MD5 SHA Mac CRC

MD5 为例

方便存储:加密后都是固定大小(32 位)的字符串,能够分配固定大小的空间存储。

损耗低:加密 / 加密对于性能的损耗微乎其微。

文件加密:只需要 32 位字符串就能对一个巨大的文件验证其完整性。

不可逆:大多数的情况下不可逆,具有良好的安全性。

推荐新的密码加密方式:

password_hash ($pwd) 使用足够强度的单向散列算法创建密码的哈希(hash)

解密

password_verify ($pwd,$secrt)

对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

对称加密方式优点:算法公开,计算量小,加密解密速度快, 加密长度没有限制.

缺点: 需要双方商定密钥并保存,密钥管理成为双方的负担。

应用场景:

相对大一点的数据量或关键数据的加密。

在对称加密算法中常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等。

AES加密算法

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

PHP的OpenSSL扩展已经实现了AES加密算法,我们可以通过OpenSSL扩展提供的方法实现对数据的加密和解密,

PHP在7.2版本已经完全移除了MCrypt加密,PHP手册在7.1迁移页面给出了替代方案,就是用OpenSSL取代MCrypt.

PHP AES实现代码:

class AES

{

//设置AES秘钥

private static $aes_key = 'bUYJ3nTV6VBasdJF'; //此处填写前后端共同约定的秘钥

/**

* 加密

* @param string $str 要加密的数据

* @return bool|string 加密后的数据

*/

public function encrypt($str) {

$data = openssl_encrypt($str, 'AES-128-ECB', self::$aes_key, OPENSSL_RAW_DATA);

$data = base64_encode($data);

return $data;

}

/**

* 解密

* @param string $str 要解密的数据

* @return string 解密后的数据

*/

public function decrypt($str) {

$decrypted = openssl_decrypt(base64_decode($str), 'AES-128-ECB', self::$aes_key, OPENSSL_RAW_DATA);

return $decrypted;

}

}

非对称加密

对称加密算法在加密和解密时使用的是同一个秘钥;而非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。

非对称加密优点:安全性更高,加密时需要公钥,解密时需要私钥,公钥时公开的,私钥不能公开, 不能泄露, 被加密字符串变长加密串长度不变。

缺点:加密与解密速度慢,加密长度有限制不能超出 密匙长度/8-11 的长度字符串加密

应用场景

适合于对安全性要求很高的场景,适合加密少量数据,比如支付数据、登录数据等。

在非对称加密中使用的主要算法有:RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。

RSA加密算法

RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:

将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。解密者拥有私钥,并且将由私钥计算生成的公钥发布给加密者。加密都使用公钥进行加密,并将密文发送到解密者,解密者用私钥解密将密文解码为明文。以甲要把信息发给乙为例,首先确定角色:

甲为加密者,乙为解密者。首先由乙随机确定一个KEY,称之为密匙,将这个KEY始终保存在机器B中而不发出来;然后,由这个 KEY计算出另一个KEY,称之为公匙。这个公钥的特性是几乎不可能通过它自身计算出生成它的私钥。接下来通过网络把这个公钥传给甲,甲收到公钥后,利用公钥对信息加密,并把密文通过网络发送到乙,最后乙利用已知的私钥,就对密文进行解码了。

以上就是RSA算法的工作流程。

算法实现过程为:

随意选择两个大的质数p和q,p不等于q,计算N=pq。

根据欧拉函数,不大于N且与N互质的整数個数為(p-1)(q-1)。

选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1)。

用以下这个公式计算d:d× e ≡ 1 (mod (p-1)(q-1))。

将p和q的记录销毁。

以上内容中,(N,e)是公钥,(N,d)是私钥。

生成私钥和公钥

生成私钥文件:

openssl genrsa -out rsa_private_key.pem 2048

利用私钥,生成公钥:

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

通过生成的公钥和私钥就可以对数据进行加解密:

PHP RSA 实现代码(公钥加密私钥解密):

class RSA

{

public $public_key = 'file:///home/web/rsa_public_key.pem';

public $private_key = 'file:///home/web/rsa_private_key.pem';

/**

* @param string $str 要加密的数据

* @param string $public_key 公钥

* @return string

*/

public function encrypt($str) {

$encrypted = '';

$pu_key = openssl_pkey_get_public($this->public_key); #此函数需要用 'file://' 开头路径才能被识别

openssl_public_encrypt($str, $encrypted, $pu_key);//公钥加密

$encrypted = base64_encode($encrypted);

return $encrypted;

}

/**

* 解密

* @param string $str 要解密的数据

* @param string $private_key 私钥

* @return string

*/

public function decrypt($str) {

$decrypted = '';

$pi_key = openssl_pkey_get_private($this->private_key); #此函数需要用 'file://' 开头路径才能被识别

openssl_private_decrypt(base64_decode($str), $decrypted, $pi_key);//私钥解密

return $decrypted;

}

}

PHP实现代码(私钥加密公钥解密):

class RSA

{

public $public_key = 'file:///home/web/rsa_public_key.pem';

public $private_key = 'file:///home/web/rsa_private_key.pem';

/**

* @param string $str 要加密的数据

* @param string $public_key 公钥

* @return string

*/

public function encrypt($str) {

$decrypted = '';

$pi_key = openssl_pkey_get_private($this->private_key); #此函数需要用 'file://' 开头路径才能被识别

openssl_private_decrypt(base64_decode($str), $decrypted, $pi_key);//私钥解密

return $decrypted;

}

/**

* 解密

* @param string $str 要解密的数据

* @param string $private_key 私钥

* @return string

*/

public function decrypt($str) {

$encrypted = '';

$pu_key = openssl_pkey_get_public($this->public_key); #此函数需要用 'file://' 开头路径才能被识别

openssl_public_encrypt($str, $encrypted, $pu_key);//公钥加密

$encrypted = base64_encode($encrypted);

return $encrypted;

}

}