php可逆加密算法有哪些,可逆加密算法

本文介绍了可逆加密算法的基础原理,包括对称式和非对称式的加密方法,如DES、AES、RSA等。然后提供了一种基于MD5的简单加密解密算法,并通过PHP实现。为了跨平台兼容,尤其是PHP与Java之间的互操作,文章升级了算法,使用异或运算并限制字符集到128个ASCII字符。同时,还展示了PHP和Java的升级版加密解密函数实现,并给出了PHP加密传输库的使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不可逆信息摘要算法(也称Hash算法)主要有:MD5,SHA系列,HMAC系列。

可逆加密算法分 对称式 和 非对称式,

对称式:DES,3DES,AES系列

非对称式:RSA,ECC椭圆曲线加密相关算法

基础可逆加密算法

简单的对称可逆加密算法原理,我们可以把它理解为一道数学题:

假设A有一个数字 88,接下来A想对它加密,拿一个密钥数7来加密,比如把它相加得到密文 88+7=95

A把加密后的95传输给B,B手上有协商好的密钥数7,同时也知道解密算法,那么B只要把密文减去密钥即可得到原来数字 95-7=88

以上传输过程中,只传递了密文95,原数字和密钥数都没被传输,也就实现了加密效果。

现实过程中,我们把这个数字看成计算机中的一个存储单位,比如字节(一个字节8比特),我们只要把这个字节做一遍数学运算,就能实现加密效果。

算法实现

根据以上思路,用PHP来实现对称加解密函数:

/**

* 加密函数

* By: Malu

* @param $data

* @param $key

* @return string

*/

public function encrypt($data, $key)

{

$key = md5($key);

$x = 0;

$len = strlen($data);

$l = strlen($key);

$char = "";

$str = "";

// 循环拼接私钥md5后的字符,组装到待加密字串长度

for ($i = 0; $i < $len; $i++) {

if ($x == $l) {

$x = 0;

}

$char .= $key[$x];

$x++;

}

for ($i = 0; $i < $len; $i++) {

// ord() 函数返回字符串的首个字符的 ASCII 值。

// 给每个字符循环 加上 私钥md5后的 ASCII 与 256 求模后的值(求模是防止长度越界,比如中文字符)

// 最后把 ASCII 值转成字符

$str .= chr((ord($data[$i]) + ord($char[$i])) % 256);

}

return base64_encode($str); // 用基础的64个字符替换

}

/**

* 解密函数

* By: Malu

* @param $data

* @param $key

* @return string

*/

public function decrypt($data, $key)

{

$key = md5($key);

$x = 0;

$data = base64_decode($data);

$len = strlen($data);

$l = strlen($key);

$char = "";

$str = "";

// 循环拼接私钥md5后的字符,组装到加密字串长度一样长

for ($i = 0; $i < $len; $i++) {

if ($x == $l) {

$x = 0;

}

$char .= substr($key, $x, 1);

$x++;

}

for ($i = 0; $i < $len; $i++) {

if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {

// 如果加密字串ASCII小于密文ASCII,表示长度已越界,需要补256

// 那么把 加密字串ASCII + 256 - 私钥md5后的字符串ASCII

$str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));

} else {

$str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));

}

}

return $str;

}

升级算法

以上代码在PHP下运行正常,但是在异构代码下运行呢?

比如PHP项目与Java项目加密传输,标准ASCII码共定义了128个字符,而以上算法用到了256位;

为了标准化,我把它限制到128个字符,我们来改进一下算法:

1.加密原文前做一次base64,把原文降为64个字符集。

2.把加法运算改成异或运算,这样就不用做越界处理。

下面是PHP实现的升级版可逆加密算法:

//url base64编码

public function urlsafe_b64encode($string)

{

$data = base64_encode($string);

$data = str_replace(array('+', '/', '='), array('-', '_', ''), $data);

return $data;

}

//url base64解码

public function urlsafe_b64decode($string)

{

$data = str_replace(array('-', '_'), array('+', '/'), $string);

$mod4 = strlen($data) % 4;

if ($mod4) {

$data .= substr('====', $mod4);

}

return base64_decode($data);

}

/**

* 加密函数 V2

* By: Malu

* @param $data

* @param $key

* @return string

*/

public function encrypt_v2($data, $key)

{

$key = md5($key);

$x = 0;

$data = $this->urlsafe_b64encode($data);

$len = strlen($data);

$l = strlen($key); // 32

$char = "";

$str = "";

// 循环拼接私钥md5后的字符,组装到待加密字串长度

for ($i = 0; $i < $len; $i++) {

if ($x == $l) {

$x = 0;

}

$char .= $key[$x];

$x++;

}

for ($i = 0; $i < $len; $i++) {

// ord() 函数返回字符串的首个字符的 ASCII 值。

// 给每个字符循环 私钥md5后的ASCII 与 与原文处理后的字符做异或运算

// 最后把 ASCII 值转成字符

$str .= chr(ord($data[$i]) ^ ord($char[$i]));

}

$str = $this->urlsafe_b64encode($str); // 可以在URL安全传输

return $str;

}

/**

* 解密函数v2

* By: Malu

* @param $data

* @param $key

* @return string

*/

public function decrypt_v2($data, $key)

{

$key = md5($key);

$x = 0;

$data = $this->urlsafe_b64decode($data);

$len = strlen($data);

$l = strlen($key);

$char = "";

$str = "";

// 循环拼接私钥md5后的字符,组装到加密字串长度一样长

for ($i = 0; $i < $len; $i++) {

if ($x == $l) {

$x = 0;

}

$char .= substr($key, $x, 1);

$x++;

}

for ($i = 0; $i < $len; $i++) {

// 把加密字串ASCII 与 私钥md5后的字符串ASCII 做异或运算

// 最后把 ASCII 值还原成字符

$str .= chr(ord(substr($data, $i, 1)) ^ ord(substr($char, $i, 1)));

}

$str = $this->urlsafe_b64decode($str);

return $str;

}

下面是Java实现的升级版可逆加密算法:

// ord() 函数返回字符串的首个字符的 ASCII 值

public static int ord(String s) {

return s.length() > 0 ? (s.getBytes(StandardCharsets.UTF_8)[0] & 0xff) : 0;

}

/**

* 加密函数 V2

* By: Malu

*

* @param data

* @param key

* @return

*/

public String encrypt(String data, String key) {

key = md5(key);

final Base64.Encoder encoder = Base64.getUrlEncoder();

byte[] textByte = new byte[0];

try {

textByte = data.getBytes("UTF-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

String encodedText = encoder.encodeToString(textByte);

Integer x = 0;

Integer len = encodedText.length();

Integer l = key.length();

String char_tmp = "";

String str = "";

// 循环拼接私钥md5后的字符,组装到待加密字串长度

for (Integer i = 0; i < len; i++) {

if (x == l) {

x = 0;

}

char_tmp += key.substring(x, x + 1);

x++;

}

for (Integer i = 0; i < len; i++) {

// ord() 函数返回字符串的首个字符的 ASCII 值。

// 给每个字符循环 私钥md5后的ASCII 与 与原文处理后的字符做异或运算

// 最后把 ASCII 值转成字符

str += (char) (ord(encodedText.substring(i, i + 1)) ^ ord(char_tmp.substring(i, i + 1)));

}

try {

textByte = str.getBytes("UTF-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

encodedText = encoder.encodeToString(textByte);

return encodedText.replace("=", ""); // 可以在URL安全传输

}

/**

* 解密函数 V2

* By: Malu

*

* @param data

* @param key

* @return

*/

public String decrypt(String data, String key) {

key = md5(key);

Integer x = 0;

String data_tmp = "";

try {

byte[] decodedBytes = Base64.getUrlDecoder().decode(data);

data_tmp = new String(decodedBytes, "utf-8");

} catch (Exception $e) {

}

Integer len = data_tmp.length();

Integer l = key.length();

String char_tmp = "";

String str_tmp = "";

// 循环拼接私钥md5后的字符,组装到加密字串长度一样长

for (Integer i = 0; i < len; i++) {

if (x == l) {

x = 0;

}

char_tmp += key.substring(x, x + 1);

x++;

}

for (Integer i = 0; i < len; i++) {

// 把加密字串ASCII 与 私钥md5后的字符串ASCII 做异或运算

// 最后把 ASCII 值还原成字符

str_tmp += (chr(ord(data_tmp.substring(i, i + 1)) ^ ord(char_tmp.substring(i, i + 1))));

}

try {

byte[] decodedBytes = Base64.getUrlDecoder().decode(str_tmp);

data_tmp = new String(decodedBytes, "utf-8");

} catch (Exception $e) {

}

return data_tmp;

}

算法加强

以上实现了基础的加密解密过程,我们可以自由改进其算法,比如把md5替换成其他哈希算法,也可以加盐,双重md5,甚至可以通过另外接口做成协商密钥,让密文随机变化,来加强加密强度。

PHP加密传输库

加解密库 php-encrypted-transmission 添加到 composer.json 配置文件

$ composer require malu/php-encrypted-transmission

升级 composer

$ composer update

使用示例

// If you installed via composer, just use this code to require autoloader on the top of your projects.

require 'vendor/autoload.php';

// Using Medoo namespace

use Malu\Encrypted\Encrypted;

$data = ["hello","malu","bbq"];

// 加密输出

$encrypt_data = Encrypted::encrypt(json_encode($data), "34f7e6dd6acf03192d82f0337c8c54ba");

echo $encrypt_data;

// 解密输出

echo Encrypted::decrypt($encrypt_data, "34f7e6dd6acf03192d82f0337c8c54ba");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值