perf: WebSocket 数据传输加密

This commit is contained in:
kuaifan 2023-03-31 20:24:23 +08:00
parent 60a41cae41
commit ab0a5898cb
5 changed files with 58 additions and 13 deletions

View File

@ -398,9 +398,22 @@ class Doo
}
}
if ($array['client_type'] === 'pgp' && $array['client_key']) {
$array['client_key'] = str_replace(["-", "_", "$"], ["+", "/", "\n"], $array['client_key']);
$array['client_key'] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n" . $array['client_key'] . "\n-----END PGP PUBLIC KEY BLOCK-----";
$array['client_key'] = self::pgpPublicFormat($array['client_key']);
}
return $array;
}
/**
* 还原公钥格式
* @param $key
* @return string
*/
public static function pgpPublicFormat($key): string
{
$key = str_replace(["-", "_", "$"], ["+", "/", "\n"], $key);
if (!str_contains($key, '-----BEGIN PGP PUBLIC KEY BLOCK-----')) {
$key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n" . $key . "\n-----END PGP PUBLIC KEY BLOCK-----";
}
return $key;
}
}

View File

@ -138,6 +138,16 @@ class WebSocketService implements WebSocketHandlerInterface
}
}
return;
/**
* 加密参数
*/
case 'encrypt':
if ($data['type'] === 'pgp') {
$data['key'] = Doo::pgpPublicFormat($data['key']);
}
Cache::put("User::encrypt:" . $frame->fd, Base::array2json($data), Carbon::now()->addDay());
return;
}
//
if ($msgId) {

View File

@ -6,6 +6,7 @@ namespace App\Tasks;
use App\Models\WebSocket;
use App\Models\WebSocketTmpMsg;
use App\Module\Base;
use App\Module\Doo;
use Cache;
use Carbon\Carbon;
use Hhxsv5\LaravelS\Swoole\Task\Task;
@ -177,10 +178,19 @@ class PushTask extends AbstractTask
Task::deliver($task);
} else {
try {
$encrypt = Base::json2array(Cache::get("User::encrypt:" . $fid));
if ($encrypt['type'] == 'pgp') {
$msg = [
'type' => 'encrypt',
'encrypted' => Doo::pgpEncryptApi($msg, $encrypt['key']),
];
}
$swoole->push($fid, Base::array2json($msg));
$tmpMsgId > 0 && WebSocketTmpMsg::whereId($tmpMsgId)->update(['send' => 1]);
if ($tmpMsgId > 0) {
WebSocketTmpMsg::whereId($tmpMsgId)->update(['send' => 1]);
}
} catch (\Throwable) {
// 发送失败
}
}
}

View File

@ -151,7 +151,7 @@ export default {
params.data = {encrypted: await dispatch("pgpEncryptApi", params.data)}
}
}
encrypt.push("client_type=pgp;client_key=" + $urlSafe((await dispatch("pgpGetLocalKey")).publicKeyB64))
encrypt.push("client_type=pgp;client_key=" + (await dispatch("pgpGetLocalKey")).publicKeyB64)
}
if (encrypt.length > 0) {
params.header.encrypt = encrypt.join(";")
@ -2843,11 +2843,19 @@ export default {
state.wsRandom = wsRandom;
//
state.ws = new WebSocket(url);
state.ws.onopen = (e) => {
state.ws.onopen = async (e) => {
wgLog && console.log("[WS] Open", e, $A.formatDate())
state.wsOpenNum++;
//
dispatch("websocketSend", {
type: 'encrypt',
data: {
type: 'pgp',
key: (await dispatch("pgpGetLocalKey")).publicKeyB64
}
})
};
state.ws.onclose = (e) => {
state.ws.onclose = async (e) => {
wgLog && console.log("[WS] Close", e, $A.formatDate())
state.ws = null;
//
@ -2856,7 +2864,7 @@ export default {
wsRandom === state.wsRandom && dispatch('websocketConnection');
}, 3000);
};
state.ws.onerror = (e) => {
state.ws.onerror = async (e) => {
wgLog && console.log("[WS] Error", e, $A.formatDate())
state.ws = null;
//
@ -2865,9 +2873,13 @@ export default {
wsRandom === state.wsRandom && dispatch('websocketConnection');
}, 3000);
};
state.ws.onmessage = (e) => {
state.ws.onmessage = async (e) => {
wgLog && console.log("[WS] Message", e);
const msgDetail = $A.formatMsgBasic($A.jsonParse(e.data));
let result = $A.jsonParse(e.data);
if (result.type === "encrypt" && result.encrypted) {
result = await dispatch("pgpDecryptApi", result.encrypted)
}
const msgDetail = $A.formatMsgBasic(result);
const {type, msgId} = msgDetail;
switch (type) {
case "open":
@ -3203,7 +3215,7 @@ export default {
passphrase: state.clientId,
userIDs: [{name: 'doo', email: 'admin@admin.com'}],
})
data.publicKeyB64 = data.publicKey.replace(/\s*-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----\s*/g, '').replace(/\n+/g, '$')
data.publicKeyB64 = $urlSafe(data.publicKey.replace(/\s*-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----\s*/g, ''))
resolve(data)
})
},

View File

@ -77,9 +77,9 @@ export function $callData(key, requestData, state) {
export function $urlSafe(value, encode = true) {
if (value) {
if (encode) {
value = String(value).replace(/\+/g, "-").replace(/\//g, "_")
value = String(value).replace(/\+/g, "-").replace(/\//g, "_").replace(/\n/g, '$')
} else {
value = String(value).replace(/-/g, "+").replace(/_/g, "/")
value = String(value).replace(/\-/g, "+").replace(/\_/g, "/").replace(/\$/g, '\n')
}
}
return value