php RSA加密传输代码示例

本文介绍了如何在PHP中使用RSA非对称加密算法进行数据加密和解密的过程。包括生成公钥私钥对,使用公钥加密敏感数据,再用私钥解密的过程,并解决了当明文长度超过限制时的加密问题。

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

涉及敏感数据的传输,双方最好约定使用加密解密。那RSA非对称加密就大有作为了。

服务端可以保留自己的私钥,发给客户端对应的公钥。这样就可以互相加解密了。php中rsa加解密实现:

首先要生成一对公钥私钥。前提是linux机器上安装了openssl命令。

生成私钥文件:

openssl genrsa -out rsa_private_key.pem 1024

利用私钥,生成公钥:

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

 

生成了一对钥匙。php代码:

<?php
ini_set('error_reporting', -1);
ini_set('display_errors', -1);

header('Content-Type: text/html; charset=utf-8');


# openssl genrsa -out rsa_private_key.pem 1024
# openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem


$private_key = file_get_contents("/home/users/xx/test/rsa_private_key.pem");
$public_key = file_get_contents("/home/users/xx/test/rsa_public_key.pem");

$pi_key = openssl_pkey_get_private($private_key);// 可用返回资源id
$pu_key = openssl_pkey_get_public($public_key);


// 加密数据
$data = array(
'id' => '1234567890',
'name' => '小明',
'mobile' => '123456',
);
$data = json_encode($data);


$encrypted = '';
$decrypted = '';

openssl_public_encrypt($data, $encrypted, $pu_key);//公钥加密
$encrypted = base64_encode($encrypted);// base64传输
echo $encrypted,"<br/>";


openssl_private_decrypt(base64_decode($encrypted), $decrypted, $pi_key);//私钥解密
echo $decrypted,"<br/>";


print_r(json_decode($decrypted, true));

 

公钥加密(openssl_public_encrypt),私钥解密(openssl_private_decrypt)。私钥加密(openssl_private_encrypt),公钥解密(openssl_public_decrypt)。都是一个道理,代码类似。

RSA加密解密有个填充方式padding的参数,不同编程语言之间交互,需要注意这个。

padding can be one of OPENSSL_PKCS1_PADDINGOPENSSL_SSLV23_PADDINGOPENSSL_PKCS1_OAEP_PADDING,OPENSSL_NO_PADDING

 

值得注意的是,如果选择密钥是1024bit长的(openssl genrsa -out rsa_private_key.pem 1024),那么支持加密的明文长度字节最多只能是1024/8=128byte;

如果加密的padding填充方式选择的是OPENSSL_PKCS1_PADDING(这个要占用11个字节),那么明文长度最多只能就是128-11=117字节。如果超出,那么这些openssl加解密函数会返回false。

 

这时有个解决办法,把需要加密的源字符串按少于117个长度分开为几组,在解密的时候以172个字节分为几组。

其中的『少于117』(只要不大于117即可)和『172』两个数字是怎么来的,值得一说。

为什么少于117就行,因为rsa encrypt后的字节长度是固定的,就是密钥长1024bit/8=128byte。因此只要encrypt不返回false,即只要不大于117个字节,那么返回加密后的都是128byte。

172是因为什么?因为128个字节base64_encode后的长度固定是172。

这里顺便普及下base64_encode。encode的长度是和原文长度有个计算公式:

$len2 = $len1%3 >0 ? (floor($len1/3)*4 + 4) : ($len1*4/3);

 

明文超出长度的代码(前提是1024bit的密钥长,OPENSSL_PKCS1_PADDING的填充方式,否则数字要变化)

复制代码

<?php


$pi_key =  openssl_pkey_get_private($private_key);// 资源类型
$pu_key = openssl_pkey_get_public($public_key);

$data = array(
    'username' => '张三1',
    'mobile' => '13321995977',
    'info' => '14bMitESqD4PYwODWmy7rrrvyFPEnJJTECLjvKB7IkrVxVDkp1XiJnGKH  
2h5syHQ5qslPSGYJ1M/XkDnGINwaLVHVD3BoKKgKg1bZn7ao5pXT+herqxaVwWs6  
ga63yVSIC8jcODxiuvxJnUMQRLaqoF6aUb/2VWc2T5MDmxLhAkEA3pwGpvXgLiWL  
3h7QLYZLrLrbFRuRN4CYl4UYaAKokkAvZly04Glle8ycgOc2DzL4eiL4l/+x/gaq  
deJU/cHLRQJBANOZY0mEoVkwhU4bScSdnfM6usQowYBEwHYY',
);


$str = json_encode($data);


$en = encrypt_rsa($str, $pu_key);


$de = decrypt_rsa($en, $pi_key);

echo $de;



function encrypt_rsa($data, $pu_key){
    $split = str_split($data, 100);// 1024bit && OPENSSL_PKCS1_PADDING  不大于117即可
    foreach ($split as $part) {
        $isOkay = openssl_public_encrypt($part, $en_data, $pu_key);
        if(!$isOkay){
            return false;
        }
        // echo strlen($en_data),'<br/>';
        $encode_data .= base64_encode($en_data);
    }
    return $encode_data;
}


function decrypt_rsa($data, $pi_key){
    $split = str_split($data, 172);// 1024bit  固定172
    foreach ($split as $part) {
        $isOkay = openssl_private_decrypt(base64_decode($part), $de_data, $pi_key);// base64在这里使用,因为172字节是一组,是encode来的
        if(!$isOkay){
            return false;
        }
        $decode_data .= $de_data;
    }
    return $decode_data;
}

复制代码

### 如何在华为云弹性云服务器(ECS)上安装和配置JDK #### 准备工作 获取华为云Flexus服务器X实例后,需先前往华为云平台重置服务器密码[^1]。 #### 登录并更新系统 登录到已准备好的华为云ECS Linux实例。为了确保系统的稳定性和安全性,建议首先执行系统软件包的全面升级: ```bash sudo yum update -y ``` #### 安装 JDK 对于希望快速完成Java开发环境搭建的用户来说,可以利用`yum`命令来简化操作流程。具体而言,通过如下指令即可实现JDK的一键式安装: ```bash sudo yum install -y java-1.8.0-openjdk-devel ``` 此方法不仅能够自动下载所需的JDK组件,还能妥善处理依赖关系,极大地方便了用户的初次设置过程[^3]。 #### 验证安装结果 安装完成后,可以通过下面这条简单的命令确认JDK是否已经正确安装以及其具体的版本号: ```bash javac -version ``` 如果返回的是类似于`javac 1.8.0_XXX`的信息,则说明安装成功;反之则可能存在问题需要进一步排查。 #### 设置JAVA_HOME环境变量 为了让其他应用程序能顺利找到所安装的JDK,通常还需要设定全局性的`JAVA_HOME`环境变量。编辑`~/.bash_profile`文件,在其中加入相应的路径声明: ```bash export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export PATH=$PATH:$JAVA_HOME/bin source ~/.bash_profile ``` 以上步骤完成后,再次运行`echo $JAVA_HOME`应能看到之前指定的目录地址,这表明环境变量已被有效激活[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值