丁香医生
丁香要求的加密方式如下:
<?php
namespace app\api\controller;
use app\common\controller\Api;
/**
* 示例接口
*/
class Demo extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
/** @var string 版本 */
protected $version = 'V1';
/** @var string 客户编号 */
protected $customId = '这里是客户编号,可以用测试的';
/** @var string 请求的接口编号 请注意该值并不固定 每个接口不同 */
protected $apiId = '接口是哪一一个';
/** @var int 时间戳 */
protected $timestamp;
/** @var string 秘钥第二行的前48位 */
protected $prefixPublicKey = '';
/** @var string 加密算法 */
protected $encryptType = 'AES-128-ECB';
/** @var string 丁香公钥 */
protected $publicKey = "";
public function setTimestamp($timestamp): self
{
$this->timestamp = $timestamp;
return $this;
}
/**
* 拼接获取AES秘钥
* @return string
*/
protected function getAesKey(): string
{
return $this->version . $this->customId . $this->apiId . $this->timestamp . $this->prefixPublicKey;
}
/**
* 数据data加密
* @ApiMethod (POST)
*/
public function test($timestamp, $data)
{
return $this->setTimestamp($timestamp)->encode($data);
}
protected function encode(array $data)
{
$data = openssl_encrypt(json_encode($data), $this->encryptType, $this->sha1prng($this->getAesKey()), OPENSSL_RAW_DATA);
return base64_encode($data);
}
//SHA1PRNG算法
protected function sha1prng(string $key)
{
return substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);
}
/*
* aes解密
* */
public function aesJi($sStr){
$a = $sStr['timestamp'];
$sStr = $sStr['data'];
$sKey = $this->version . $this->customId . $this->apiId ."$a". $this->prefixPublicKey;
$sKeys = self::sha1prng($sKey);
$decrypted = openssl_decrypt(base64_decode($sStr), 'AES-128-ECB', $sKeys, OPENSSL_RAW_DATA);
return $decrypted;
}
//rsa加签 sha1WithRSA 签名
public function genSign()
{
//公钥拼接
$cert = "-----BEGIN PUBLIC KEY-----\n" . $this->publicKey . "\n-----END PUBLIC KEY-----";
//解析公钥
$res = openssl_pkey_get_public($cert);
//返回包含密钥详情的数组
$detail = openssl_pkey_get_details($res);
//释放密钥资源
openssl_free_key($res);
$encrypt_data = '';
//使用公钥加密数据
openssl_public_encrypt($this->getAesKey(), $encrypt_data, $detail['key']);
$encrypt_data = base64_encode($encrypt_data);
return $encrypt_data;
}
//校验 sha1WithRSA 解签
public function verifySign($data){
$data1 = base64_decode($data['sign']);
// halt($data);
$cert = "-----BEGIN PUBLIC KEY-----\n" . $this->publicKey . "\n-----END PUBLIC KEY-----";
$encrypt_data = '';
$pubKey = openssl_public_decrypt($data1,$encrypt_data,$cert);
if ($pubKey){
return $this->aesJi($data);
}
}
// post请求
public function postSend($res)
{
header("Content-type: text/html; charset=utf-8");
// 请求参数准备
$url = "https://ygj.zydxcare.cn/manage/openapi/handle";
$tojson = json_encode($res);
$header[] = "Content-Type: application/json; charset=utf-8";
$header[] = "Data-signature:C80310638874448266292D70EFA9340C";
$header[] = "Time-stamp:1515577396000";
// print_r($tojson);die();
//初始化
$ch = curl_init();
// 设置请求地址
curl_setopt($ch, CURLOPT_URL, $url);
// 设置头文件
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
// 设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 设置POST形式传参
$a = curl_setopt($ch, CURLOPT_POST, 1);
// 设置POST请求参数
curl_setopt($ch, CURLOPT_POSTFIELDS, $tojson);
// 设置ssl请求
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// var_dump(curl_error($ch));
// 开始CURL请求
$data = curl_exec($ch);
// 关闭URL请求
curl_close($ch);
// print_r($data);die();
//打印获得的数据
$data = json_decode($data,true);
if (empty($data['code'])){
$this->error('错误');
}
return $data;
}
//拼接数据
public function index()
{
$res = request()->post();
$timestamp = $res['timestamp'];
$da = $res['data'];
$res['data'] = $this->test($timestamp, $da);
$sign = $this->genSign();
$data = [
"apiId" => $res['apiId'],
"customId" => $this->customId,
"timestamp" => $res['timestamp'],
"version" => $this->version,
"data" => $res['data'],
"sign" => $sign
];
$information = $this->postSend($data);
return $this->verifySign($information);
}
}
请求如下
仿照实现接口加密方案
php代码
// 要加密的原始数据
$data = 'Hello, World!';
// 加密密钥
$key = 'YourEncryptionKey';
// 加密算法和加密模式
$algorithm = 'AES-256-CBC';
$ivLength = openssl_cipher_iv_length($algorithm);
$iv = openssl_random_pseudo_bytes($ivLength);
// 加密数据
$encryptedData = openssl_encrypt($data, $algorithm, $key, OPENSSL_RAW_DATA, $iv);
// Base64编码加密后的数据和初始化向量(IV)
$encryptedDataBase64 = base64_encode($encryptedData);
$ivBase64 = base64_encode($iv);
// 返回加密后的数据和IV给前端
return json(['encryptedData' => $encryptedDataBase64, 'iv' => $ivBase64]);
前端解密
// 接收前端传递的加密数据和IV
$encryptedDataBase64 = $_POST['encryptedData'];
$ivBase64 = $_POST['iv'];
// 解密密钥
$key = 'YourEncryptionKey';
// 解码加密数据和IV
$encryptedData = base64_decode($encryptedDataBase64);
$iv = base64_decode($ivBase64);
// 解密数据
$decryptedData = openssl_decrypt($encryptedData, $algorithm, $key, OPENSSL_RAW_DATA, $iv);
// 处理解密后的数据
echo $decryptedData;