php中文加密解密,php加密解密详解

不知道大家对于php加密解密有多少了解,本文主要和大家分享php加密解密相关知识,希望能帮助到大家。

一 对称加密

1.mycyrpt的对称加密:/**

* @param $key //数据加密密钥 由自己定义,长度有限制 string

* @param $string //需要进行加解密的字符串 string

* @param $decrypt //加密还是解密 (最简单的,0代表加密,1代表解密)

* @return string */

function encryptDecrypt($key, $string, $decrypt)

{

if(!$decrypt){

//加密

$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));

return $encrypted;

}else{

//解密

$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($string), MCRYPT_MODE_CBC, md5(md5($key))), "12");

return $decrypted;

}

}//使用方法:echo encryptDecrypt('passwordgg', 'Hello欢迎您',0);

//加密

ZbKOQy8uarg6nsIrpjZnJvaIDMuAAIBH3sjhBEqYujM=echo encryptDecrypt('passwordgg', 'ZbKOQy8uarg6nsIrpjZnJvaIDMuAAIBH3sjhBEqYujM=',1);

//解密

Hello欢迎您

注: 此方法php7.1开始已经被废弃,开始采用openssl_encrypt和openssl_decrypt , 官方推荐使用openssl一族进行加解密

2.OpenSSL 扩展中的对称加密/**

* @param string $data 需要加解密的数据字符串 string

* @param int $yes 加密还是解密(1表示加密,0表示解密)

* @param string $key 数据加密密钥

* @param string $iv 初始化向量 //注:这里为了显示效果,暂时将iv存储到session中,

* @param string $iv 实际应用中,应该将iv和加密后的字符串都存储在数据库

* @param string $encryptMethod

数据加密方式 100余种,可通过openssl_get_cipher_methods()函数获取,

* @param string $encryptMethod 选择其中一种(如果选择cbc结尾的加密算法,

需要初始化向量iv,如本例)

* @return string

*/

function openssl_crypt($data='',$yes=1,$key='secret',$iv='',$encryptMethod='aes-256-cbc'){

if($yes)

{

$ivLength = openssl_cipher_iv_length($encryptMethod); //获取该加密算法iv应该具有的长度

$iv = openssl_random_pseudo_bytes($ivLength, $isStrong); //生成iv(初始化向量)

if (false === $iv && false === $isStrong)

{

die('IV generate failed');

}

//加密

$encrypted = openssl_encrypt($data, $encryptMethod, $key, 0, $iv);

$_SESSION['iv']=$iv; //将iv存到session中

return $encrypted;

}else{

//解密

$decrypted = openssl_decrypt($data, $encryptMethod, $key, 0, $iv);

return $decrypted;

}

}//使用方法

echo $a=openssl_crypt('我爱北京天安门 /我爱祖国',1,'passG506'); //加密

LMcwSGlTFijXRdcPaccYoc08xgr7NydtZ+Wrhdv/145gF3/ayKQCJvRLmvhs5ec8echo "
";

echo openssl_crypt($a,0,'passG506',$_SESSION['iv']); //解密 我爱北京天安门 /我爱祖国

注: 1. 为什么要生成iv,iv的作用是什么

回顾一下 openssl_get_cipher_methods() 返回的加密算法列表,有很多名字中间带有 “CBC” 字样,这些加密算法使用了同一种加密模式,也就是 密码分组链接模式(Cipher Block Chaining)。

在 CBC 模式的加密算法中,明文会被分成若干个组,以组为单位加密。每个组的加密过程,依赖他前一个组的数据:需要跟前一组的数据进行异或操作后生成本组的密文。那么最开头的那个组又要依赖谁呢?依赖的就是 IV,所以这就是为什么 IV 要叫初始化向量。IV 是 初始化向量(initialization vector)的缩写

IV 应该是随机生成的,所以代码用到了 openssl_random_pseudo_bytes() 生成 IV。该函数接收一个 int,代表需要生成的 IV 的长度。

IV 长度随加密算法不同而不同。一般人是记不住那么多算法需要的 IV 长度的。所以直接使用 openssl_cipher_iv_length() 函数,这个函数返回一个 int,表示加密算法需要的 IV 长度:echo openssl_cipher_iv_length('AES-256-CBC'); // 16

echo openssl_cipher_iv_length('BC-CBC'); // 8

echo openssl_cipher_iv_length('AES-128-ECB'); // 0

比如 AES-256-CBC 需要16位的 IV、 BC-CBC 需要 8 位的 IV、而AES-128-ECB 不需要 IV,所以返回了 0。

2. 在使用过程中需要注意的问题

在进行加解密时,两个函数除了第一个参数不同,其余参数都要保证相同才能顺利解密。最后,在使用需要 IV 的加密算法时,需要注意:

必须传 $iv 参数,不传的话PHP将会抛出一个 Warning

IV 应该是随机生成的(比如用 openssl_random_pseudo_bytes() ),不能人为设定

每次加密都应该重新生成一次 IV ,不可偷懒多次加密采用相同 IV

IV 要随着密文一起保存(不然就没法解密啦),可以直接附在密文串后面,也可以分开保存

如果看不懂,可以参考对称加密

二 非对称加密

常用的非对称加密有RSA算法,非对称加密和解密使用的是不同的密钥,其中一个对外公开作为公钥,另一个只有私有者拥有,作为私钥。

用私钥加密的信息只有公钥才能解开,或者反之用公钥加密的信息只有私钥才能解开。

在RSA加解密之前,需要先生成一对公私钥,可使用Linux自带的RSA密钥生成工具openssl获取一对公私钥,也可以使用PHP openssl扩展函数生成一对公私钥。

可参考:RSA非对称加密

注:非对称加密的缺点是机密和解密花费时间长,速度慢,只适合对少量数据进行加密。

如果既想有很快的加密速度,又想保证数据比对称加密更安全,可以使用混合加密。(即 对数据进行对称加密,对密钥做非对称加密)

解密的时候,先用非对称加密得到密钥,再用密钥解开密文得到明文。

相关推荐:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ElGamal算法是一种非对称加密算法,与RSA算法类似,它也是基于数论的,但是与RSA算法不同的是它的加密和解密使用的是同一个密钥对,而且加密和解密过程都需要进行一些随机化处理。 下面是ElGamal算法的加解密C语言实现: 加密过程: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> // 求模幂运算 a^b mod m long long mod_pow(long long a, long long b, long long m) { long long ans = 1; while (b > 0) { if (b & 1) { ans = (ans * a) % m; } a = (a * a) % m; b >>= 1; } return ans; } // 生成一个大素数 long long get_prime(long long min, long long max) { long long i, j; for (i = min; i <= max; i++) { for (j = 2; j <= sqrt(i); j++) { if (i % j == 0) { break; } } if (j > sqrt(i)) { return i; } } return -1; } // 生成一个随机数 long long get_random(long long min, long long max) { return rand() % (max - min + 1) + min; } int main() { long long p, g, x, y, k, m, c1, c2; srand(time(0)); // 生成大素数 p p = get_prime(10000, 20000); // 选择一个原根 g for (g = 2; g < p; g++) { int flag = 1; for (int i = 1; i < p - 1; i++) { if (mod_pow(g, i, p) == 1) { flag = 0; break; } } if (flag) { break; } } // 生成私钥 x x = get_random(2, p - 2); // 计算公钥 y y = mod_pow(g, x, p); // 加密 printf("请输入要加密的明文:"); scanf("%lld", &m); k = get_random(2, p - 2); c1 = mod_pow(g, k, p); c2 = m * mod_pow(y, k, p) % p; printf("密文为:(%lld, %lld)\n", c1, c2); return 0; } ``` 解密过程: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> // 求模幂运算 a^b mod m long long mod_pow(long long a, long long b, long long m) { long long ans = 1; while (b > 0) { if (b & 1) { ans = (ans * a) % m; } a = (a * a) % m; b >>= 1; } return ans; } int main() { long long p, x, c1, c2, m; scanf("%lld%lld%lld%lld", &p, &x, &c1, &c2); // 解密 m = c2 * mod_pow(c1, p - 1 - x, p) % p; printf("明文为:%lld\n", m); return 0; } ``` 其中,加密过程中,首先生成一个大素数p,然后选择一个原根g,然后生成私钥x和公钥y。加密时,选择一个随机数k,计算密文c1和c2。解密时,根据公式,将密文c1、c2、私钥x和大素数p带入即可计算出明文m。 需要注意的是,由于ElGamal算法加密过程中需要进行随机化处理,因此同样的明文在不同的加密过程中得到的密文是不同的,这也是ElGamal算法的特点之一。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值