数字签名
比方说接入苹果登录的时候,app会获取到苹果服务器返回的jwt数据(称之为identityToken),而这个jwt(参考:www.ruanyifeng.com/blog/2018/0…
这个jwt由3部分构成:header.payload.signature。
header: 包括了key id 与加密算法
payload:
iss: 签发机构,苹果
aud: 接收者,目标app
exp: 过期时间
iat: 签发时间
sub: 用户id
c_hash: 一个哈希数列,作用未知
auth_time: 签名时间
signature: 用于验证JWT的签名
其中的signature是用苹果服务器的私钥加密的,因此只能由苹果服务器的公钥解密。
应用服务器在获取对应该私钥的公钥的时候会去访问:appleid.apple.com/auth/keys,得…
称之为N和E,然后通过一系列操作,将N和E转化为PEM格式的公钥,拿到该公钥就可以解密signature,得到一串明文。
再拿解密之后的数据与hash(header.payload)得到的数据做对比即可得知数据是否被篡改过。
-
疑问一:有没有可能jwt串被第三方恶意替换过? 不可能,因为应用服务器在做校验的时候会从苹果官网去获取公钥(除非获取公钥的过程被黑了,这个无法严格保证),因为这个signature串不是用苹果的私钥加密的,一定解不开这个jwt串里的signature,所以这个串一定有问题。
-
疑问二:有没有可能jwt串的header和payload被改掉了,然后签名用真的? 不行,因为,签名即时成功解密了,因为header.payload被换掉了,通过hash(header.payload)得到的串与解密签名得到 的串肯定不对应,则证明内容被篡改过。
综上,数字签名首先保证数据是来自于正确的人(因为可以被正确的公钥解密),其次保证数据本身的正确的(因为原始数据hash之后得到的数据串与公钥解密得到的数据串一致)。
数字证书
数字证书一般由数字证书认证机构(Certificate Authority)颁发。数字证书里包含了真实服务器(比如知乎)的公钥和一些其他信息。
数字证书本身是被认证机构CA用自己的私钥加密而得的。当用户访问某网站获取到服务器的数字证书之后,浏览器使用数字证书机构的公钥(可以简单理解为根证书)解密后得到真实服务器的公钥。利用该真是服务器的公钥即可开展后续的数据通信。
这里的关键是数字证书机构的公钥是内置与操作系统中的,在系统初始化的时候就已经安装好的,我们无理由信任的,除非你不信任微软或者自己作死,利用超级权限改掉了内置的根证书。