之前已经可以用後端的套件去实作推播的服务器,但那个套件实际上做了哪些事情?
流程如下图,相关定义可参考连结:
https://datatracker.ietf.org/doc/html/draft-ietf-webpush-encryption
+-------+ +--------------+ +-------------+
| UA | | Push Service | | Application |
+-------+ +--------------+ +-------------+
| | |
| Setup | |
|<====================>| |
| Provide Subscription |
|-------------------------------------------->|
| | |
: : :
| | Push Message |
| Push Message |<---------------------|
|<---------------------| |
| | |
也因为定义了标准协议的关系,所以有了各语言的实作版本:
密钥会用来检查订阅的用户身分公钥是否符合,pushManager.subscribe()
会用公钥来检查接收到的签章讯息是否由与公钥相关的私钥签出来的。
签章讯息的传递会透过 JWT 放在 header 进行资料交换,一个 JWT 会由三段字串组成并由 .
号分隔 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCJ9.zTWqeQdfDM0WKGBFig2-VmUpTLkIQ4DvAJN6_LzDZzU
,前两个字串(JWT info 和 JWT data)是经过 base64 编码的 JSON ,所以其实是公开可阅读的。
想要解密 JWT,可以直接用官方网站提供的介面。
https://jwt.io/
{
"//": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
"alg": "HS256",
"typ": "JWT"
}
https://github.com/web-push-libs/vapid
{
"//": "`eyJuYW1lIjoidGVzdCJ9",
"aud": "https://YourSiteHere.example",
"sub": "mailto://[email protected]",
"exp": 1457718878
}
最後的 header 就会像是 Authorization: 'WebPush <JWT Info>.<JWT Data>.<Signature>'
推播的讯息不能赤裸裸的传递,所以在加密上也有定义相关规范,我也看不是很懂,总体来说就是套了加密、加盐、金钥对搭配使用,执行加密的时候最後也加上填充,避免被用长度推断。
看不懂也没关系可以看影片,但我相信看完影片可能还是只懂概念。
https://youtu.be/F3zzNa42-tQ
const keyCurve = crypto.createECDH("prime256v1");
keyCurve.generateKeys();
const publicKey = keyCurve.getPublicKey();
const privateKey = keyCurve.getPrivateKey();
function hkdf(salt, ikm, info, length) {
// ikm 加盐
const keyHmac = crypto.createHmac("sha256", salt);
keyHmac.update(ikm);
const key = keyHmac.digest();
// info 加密
const infoHmac = crypto.createHmac("sha256", key);
infoHmac.update(info);
const ONE_BUFFER = new Buffer(1).fill(1);
infoHmac.update(ONE_BUFFER);
// 长度控制
return infoHmac.digest().slice(0, length);
}
const nonce = hkdf(salt, prk, nonceInfo, 12);
const contentEncryptionKey = hkdf(salt, prk, cekInfo, 16);
使用者装置:
服务器:
<<: [Day 24] Android Studio 七日陨石开发:安装与创建第一个专案 (下)
work 和 listen 的差别 让 queue work 开始执行任务的指令有两个:work 和...
看到标题有个(二)该不会又是很长的系列文了吧!? 并不会。 因为有点复杂。微懒。 抓取目前所在位子 ...
标示超连结 < a>元素是用来标示超连结,常使用的属性为< href> &l...
环境建置 LINE Provider 创建 在LINE Developers网站右上角登入LINE帐...
对於资料库管理员而言, 另一项重要任务是异质平台之间的资料沟通. 接下来实作从SQL到NSQL的资料...