我组装了一个 json-rpc 2.0 服务器以更好地理解该协议。我终于到了开始考虑保护它并继续学习基本身份验证的部分。
在标准的 Basic Auth 中,您会看到以下工作流程:
向
/jsonrpc
发出 POST 请求,包括 HTTP 标头 Authorization: Basic dXNlcjE6bGV0bWVpbg==
此标头值等于
user1:letmein
编码为 base64
> POST /jsonrpc HTTP/1.1
> Host: 10.10.1.100:3000
> User-Agent: insomnia/2022.7.5
> Content-Type: application/json
> Authorization: Basic dXNlcjE6bGV0bWVpbg==
> Accept: */*
> Content-Length: 0
以 JSON 格式接收响应,包括用于后续请求的令牌。
< HTTP/1.1 200 OK
< access-control-allow-methods: POST
< access-control-allow-origin: *
< allow: POST
< cache-control: no-store
< content-language: en-US
< content-type: application/json; charset=UTF-8
< server: JSON-RPC 2.0 Server
< vary: Accept-Encoding
< content-length: 143
< date: Mon, 06 Mar 2023 21:28:18 GMT
{
"jsonrpc": "2.0",
"method": "auth",
"result": {
"token": "3c469e9d6c5875d37a43f353d4f88e61fcf812c66eee3457465a40b0da4153e0",
"expires": 1678141698081
}
}
我的问题是,显然,base64 也可能是通过网络发送的纯文本,所以它不安全。
会用
Web Crypto API SubtleCrypto.digest()方法中的
base64
替换 sha256
编码使它更安全,还是只是一样和天真。
const encoder = new TextEncoder();
async function sha256(message: string): Promise<string> {
// encode as (utf-8) Uint8Array
const msgUint8: Uint8Array = encoder.encode(message);
// hash the message
const hashBuffer: ArrayBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
// convert buffer to byte array
const hashArray: number[] = Array.from(new Uint8Array(hashBuffer));
// convert bytes to hex string
const hashHex: string = hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
// return hex string
return hashHex;
}