1、合作商余额查询
2、分油账户司机可用额度
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | RSA 密钥自检 —— 排查下游报 errCode=0007「请求参数解析异常」(CLI)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 0007 的实际含义是:我方用【平台私钥】解不开下游加密的 AES 密钥。
|
||||
// | 报错里的「PEM routines:no start line」是 OpenSSL 错误队列的残留信息,
|
||||
// | 具有误导性,真正原因几乎都是:下游加密时用的公钥 ≠ 我方平台私钥对应的公钥。
|
||||
// |
|
||||
// | 用法(站点根目录执行):
|
||||
// | php deploy/rsa_check.php 自检密钥对 + 打印要发给下游的公钥
|
||||
// | php deploy/rsa_check.php <appKey> 再检查该合作商的公钥(用于验签其请求)
|
||||
// | php deploy/rsa_check.php <appKey> "<key密文>" 用请求里的 key 字段实测能否解开
|
||||
// |
|
||||
// | 其中「key密文」是下游请求体 {"key":"...","data":"..."} 里的 key 原值。
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
http_response_code(403);
|
||||
exit('仅限命令行执行');
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
$appKey = $argv[1] ?? '';
|
||||
$encKey = $argv[2] ?? '';
|
||||
|
||||
function line(): void
|
||||
{
|
||||
echo str_repeat('-', 62) . "\n";
|
||||
}
|
||||
|
||||
/** 取密钥指纹,便于和对方核对是不是同一把 */
|
||||
function fingerprint($keyRes): string
|
||||
{
|
||||
$d = openssl_pkey_get_details($keyRes);
|
||||
return isset($d['rsa']['n']) ? strtoupper(substr(md5($d['rsa']['n']), 0, 16)) : '(取不到)';
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 1. 平台密钥对
|
||||
// ================================================================
|
||||
echo "【1】平台密钥对\n";
|
||||
line();
|
||||
|
||||
$privPath = $root . '/rsa/private_key.pem';
|
||||
$pubPath = $root . '/rsa/public_key.pem';
|
||||
|
||||
foreach ([$privPath, $pubPath] as $p) {
|
||||
printf(" %-28s %s\n", basename($p), is_file($p) ? '存在(' . filesize($p) . ' 字节)' : '❌ 不存在');
|
||||
}
|
||||
if (!is_file($privPath) || !is_file($pubPath)) {
|
||||
exit("\n❌ 密钥文件缺失,下游所有请求都会失败。\n");
|
||||
}
|
||||
|
||||
$priv = openssl_pkey_get_private(file_get_contents($privPath));
|
||||
$pub = openssl_pkey_get_public(file_get_contents($pubPath));
|
||||
printf(" 平台私钥加载%s\n", $priv ? '成功' : '❌ 失败:' . openssl_error_string());
|
||||
printf(" 平台公钥加载%s\n", $pub ? '成功' : '❌ 失败:' . openssl_error_string());
|
||||
if (!$priv || !$pub) {
|
||||
exit("\n❌ 密钥文件格式不对,请检查是否为完整 PEM(含 BEGIN/END 行)。\n");
|
||||
}
|
||||
|
||||
$dPriv = openssl_pkey_get_details($priv);
|
||||
$dPub = openssl_pkey_get_details($pub);
|
||||
printf(" 位数:私钥 %d / 公钥 %d\n", $dPriv['bits'], $dPub['bits']);
|
||||
$pairOk = $dPriv['key'] === $dPub['key'];
|
||||
printf(" 两者是否同一对:%s\n", $pairOk ? '是' : '❌ 否(公私钥不配套,必须换成同一对)');
|
||||
|
||||
// 实测闭环
|
||||
$aes = openssl_random_pseudo_bytes(32);
|
||||
openssl_public_encrypt($aes, $enc, $pub, OPENSSL_PKCS1_PADDING);
|
||||
$loopOk = openssl_private_decrypt($enc, $dec, $priv, OPENSSL_PKCS1_PADDING) && $dec === $aes;
|
||||
printf(" 加密→解密闭环:%s\n", $loopOk ? '通过' : '❌ 失败');
|
||||
printf(" 平台公钥指纹:%s\n", fingerprint($pub));
|
||||
|
||||
// ================================================================
|
||||
// 2. 发给下游的公钥(他们必须用这一把加密 AES 密钥)
|
||||
// ================================================================
|
||||
echo "\n【2】请把下面这把【平台公钥】发给下游,让他们核对\n";
|
||||
line();
|
||||
echo trim(file_get_contents($pubPath)) . "\n\n";
|
||||
echo "一行 base64(Java 可直接用):\n";
|
||||
echo preg_replace('/\s+/', '', str_replace(['-----BEGIN PUBLIC KEY-----', '-----END PUBLIC KEY-----'], '', file_get_contents($pubPath))) . "\n";
|
||||
|
||||
// ================================================================
|
||||
// 3. 合作商公钥(我方用它验签下游请求)
|
||||
// ================================================================
|
||||
if ($appKey !== '') {
|
||||
echo "\n【3】合作商 {$appKey}\n";
|
||||
line();
|
||||
try {
|
||||
$ini = @parse_ini_file($root . '/.env', true, INI_SCANNER_RAW) ?: [];
|
||||
$db = $ini['DATABASE'] ?? [];
|
||||
$pdo = new PDO(
|
||||
'mysql:host=' . ($db['HOSTNAME'] ?? '127.0.0.1') . ';port=' . ($db['HOSTPORT'] ?? '3306')
|
||||
. ';dbname=' . ($db['DATABASE'] ?? 'oil') . ';charset=' . ($db['CHARSET'] ?? 'utf8'),
|
||||
$db['USERNAME'] ?? 'root', $db['PASSWORD'] ?? '',
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
|
||||
);
|
||||
$st = $pdo->prepare('SELECT partners_id, name, orgNo, appKey, publicKey, privateKey FROM yoshop_partners WHERE appKey = ? LIMIT 1');
|
||||
$st->execute([$appKey]);
|
||||
$p = $st->fetch();
|
||||
if (!$p) {
|
||||
echo " ❌ 未找到该 appKey 的合作商\n";
|
||||
} else {
|
||||
printf(" 合作商:%s(partners_id=%s,orgNo=%s)\n", $p['name'], $p['partners_id'], $p['orgNo']);
|
||||
$ppub = openssl_pkey_get_public((string) $p['publicKey']);
|
||||
printf(" 合作商公钥:%s%s\n", $ppub ? '可加载' : '❌ 无法加载:' . openssl_error_string(),
|
||||
$ppub ? ' 指纹 ' . fingerprint($ppub) : '');
|
||||
echo " 用途:我方用它验签下游请求。下游必须用与之配套的私钥加签,否则报 0006。\n";
|
||||
if (!empty($p['privateKey'])) {
|
||||
$ppriv = openssl_pkey_get_private((string) $p['privateKey']);
|
||||
if ($ppub && $ppriv) {
|
||||
$dd = openssl_pkey_get_details($ppriv);
|
||||
printf(" 库里另存的合作商私钥与其公钥是否配套:%s\n",
|
||||
$dd['key'] === openssl_pkey_get_details($ppub)['key'] ? '是' : '❌ 否');
|
||||
echo " (这把私钥是发给下游用的,请确认下游手里就是它)\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
echo ' 查询失败:' . $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 4. 用真实请求里的 key 密文实测
|
||||
// ================================================================
|
||||
if ($encKey !== '') {
|
||||
echo "\n【4】实测解密下游请求里的 key\n";
|
||||
line();
|
||||
$raw = base64_decode($encKey, true);
|
||||
if ($raw === false) {
|
||||
echo " ❌ 不是合法 base64\n";
|
||||
} else {
|
||||
printf(" 密文长度:%d 字节(%d 位密钥应为 %d 字节)\n", strlen($raw), $dPriv['bits'], $dPriv['bits'] / 8);
|
||||
while (openssl_error_string() !== false) {
|
||||
// 先清空 OpenSSL 错误队列,避免读到别处残留的 PEM 报错
|
||||
}
|
||||
$ok = openssl_private_decrypt($raw, $out, $priv, OPENSSL_PKCS1_PADDING);
|
||||
if ($ok) {
|
||||
printf(" ✅ 解密成功,AES 密钥长度 %d 字节(应为 32)\n", strlen($out));
|
||||
echo " 说明密钥是配套的,0007 的原因在别处,请把完整请求发来再看。\n";
|
||||
} else {
|
||||
echo " ❌ 解密失败:" . (openssl_error_string() ?: '无附加信息') . "\n";
|
||||
echo " 结论:下游加密用的公钥,与我方平台私钥不是一对。\n";
|
||||
echo " 让下游换成【2】里打印的那把平台公钥即可。\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
Reference in New Issue
Block a user