网站首页php

接口数据加密传输

发布时间:2023-04-04 16:40:02编辑:slayer.hover阅读(1030)

    1. 使用openssl生成公钥和私钥
    #生成私钥

    openssl genrsa -out privateKey.pem 2048


    #生成公钥

    openssl rsa -in privateKey.pem -outform PEM -pubout -out publicKey.pem


    获取公钥文件publicKey.pem和私钥文件privateKey.pem.

    2. 后端PHP使用公钥加密, 私钥解密数据
    #加密数据

    因为RSA加解密中, 明文长度需要小于密钥长度(2048),而密文长度则等于密钥长度,所以当加密内容长度大于密钥长度时,就需要对内容进行分段处理。

    PKCS#1建议的padding占用11个字节。

    对于2048长度的密钥,256字节 - 11字节 = 245字节,所以每次参与加密的明文只有245字节。

    我们将数据分段后逐一加密,再将结果进行拼接。

    function encrypt($plainText){
        $pubKey = file_get_contents('./publicKey.pem');
        $key        = openssl_pkey_get_public($pubKey);
        if (!$key) {
            throw new Exception('公钥不可用');
        }
        $crypto = [];
        foreach (str_split($textToEncrypt, 245) as $chunk) {
            openssl_public_encrypt($chunk, $encryptData, $pubKey);
            $crypto[] = base64_encode($encryptData);
        }
        return implode('|||', $crypto);
    }


    #解密数据

    同样,解码也需要分段解码,并将结果进行拼接。

    function decrypt($cipherText){
        $priKey = file_get_contents('./privateKey.pem');
        $key      = openssl_pkey_get_private($priKey);
        $crypt   = '';
        foreach (explode('|||', $cipherText) as $chunk) {
            openssl_private_decrypt($chunk, $decryptData, $priKey);
            $crypt .= base64_decode($decryptData);
        }
        return $crypt;
    }


    3. 前端JS使用公钥加密, 私钥解密数据

    a. 安装依赖, 引入jsencrypt

    npm install jsencrypt


    b. 封装个encrypt.js

    //引入
    import { JSEncrypt } from 'jsencrypt'
    /**
     * 加密
     * @param {String}  需要加密的参数
     */
    export function encrypt (text) {
      const publicKey = '...'
      let jscrypt = new JSEncrypt()
      jscrypt.setPublicKey(publicKey)
      return jscrypt.encrypt(text)
    }
     
    // 解密
    export function decrypt (text) {
      const privateKey = '...'
      let jscrypt = new JSEncrypt()
      jscrypt.setPrivateKey(privateKey)
      return jscrypt.decrypt(text)
    }

    c. 使用获取接口密文, 并分段解析

    <script>
    //引入encrypt.js
    import { encrypt, decrypt } from '@/encrypt.js'
        ...
        test () {     
    		//加密
    		let coder = { code: 200, msg: 'OK' };
    		let cipherText = encrypt ( JSON.encode(coder) );
    		console.log( cipherText );
    
    		//解密            
    		let resp = cipherText.split('|||');
    		let rest = '';
    		resp.forEach((block)=>{
    			rest += decrypt(block);
    		})
    		response = JSON.parse(rest);
    		console.log( response );
        }
    </script>


评论