【无RS256和HS256的区别,他们与SHA-256的联系标题】

什么是RSA

全称:由美国麻 省理工 学院三 位学者 Riv est、Sh amir 及Adleman 研 究发 展出 一套 可实 际使用 的公 开金 钥密码系 统,那 就是RSA(Rivest-Shamir-Adleman)密码系统。

RS256

RS256(带有SHA-256的 RSA 签名)是一种非对称算法,它使用公钥/私钥对:身份提供者拥有用于生成签名的私钥(秘密)密钥,而 JWT 的消费者获得公钥验证签名。由于与私钥相反,公钥不需要保持安全,因此大多数身份提供者都可以让消费者轻松获取和使用(通常通过元数据 URL)。

HS256

另一方面, HS256(带有 SHA-256 的HMAC)涉及散列函数和一个(秘密)密钥的组合,该密钥在两方之间共享,用于生成用作签名的散列。由于生成签名和验证签名都使用相同的密钥,因此必须注意确保密钥不被泄露。

1 SHA-256:

SHA(Secure Hash Algorithm,安全散列算法)是一个密码散列函数家族,由美国国家安全局(NSA)设计,并由美国国家标准与技术研究院(NIST)发布,是美国的政府标准。包括 SHA-0系列、SHA-1系列、SHA-2系列和SHA-3系列。SHA-256SHA-2系列函数之一
对于SHA-256

  • 无论输入多长,都输出64个字符,共32字节(byte),256位(bit)
  • 输出只包含数字0~9和字母A~F,大小写不敏感

2 RS-256和HS-256的区别

3 JWT 使用HS-256的加解密过程

加密:

首先jwt分为header.payload.signature三个部分构成,

  1. 当我们对header和payload进行填充后,会进行用base64url对他们分别进行编码,记为A和B,假设未经过base64url编码的header和payload分别如下所示:
header: {
  "alg": "HS256",
  "typ": "JWT"
}
header编码后变成了:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9,记位A
payload: {
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
payload编码后变成了:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9,记位B

2. 随后使用HS256加密算法对header和payload以及认证服务器本身拥有的密钥进行加密,其加密公式如下:

加密公式:HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret code ),

解释一下HMACSHA256,也即是SHA256加密算法,是一个总是输出256bit长的字符串的散列函数,

加密后,最终得到的结果是64位的字符串: IgfIWP_XtusfBW3ltGuDKdGk4xJZkOjmyoqkjkAkWSI, 记为C,这个C其实就是HMAC(Hash Based Message Authentication Code即基于hash函数的信息验证码)

3. 最后再将A, B, C拼接在一起

即A + B + C = base64UrlEncode(header) + base64UrlEncode(payload) + C = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.IgfIWP_XtusfBW3ltGuDKdGk4xJZkOjmyoqkjkAkWSI"

解密:

  1. 拿到jwt后,会对使用SHA256对header和payload(未被解码)并结合密钥进行加密,加密公式以上加密的第二个步骤的HMACSHA256一样,
  2. 如果得到的结果和signature函数一摸一样,则认证成功。

4 JWT 使用RS256的加解密过程

加密:

  1. 当认证服务器收到用户的登录信息后,将用户唯一标识符装进payload信息中,随后对header和payload进行填充后,会进行用base64url对他们分别进行编码,记为A和B,假设未经过base64url编码的header和payload分别如下所示:
  2. 然后再使用SHA-256对(A + "." + B) 这一字符串进行哈希处理,得到一个只有256bit的字符串C,
  3. 再使用RSA256对哈希结果C进行加密,加密过程使用到了私钥,加密形式为RSA256(C, private secret key), 得到一个最终的数字签名D,
  4. 最终将A,B, D拼接成A + "." + B + "." + D的形式发送给客户端

解密过程:

  1. 应用服务器会使用公钥对收到jwt中的signature签名解密得到一个hash码,
  2. 再使用SHA-256对收到jwt的header,payload进行一起哈希,公式为SHA-256(header + "." + payload), 其中的"."不能掉
  3. 将签名中解密得到的hash值和刚使用Header和Payload参与计算的哈希值进行比较,如果两个哈希值相等,则证明JWT确实是由认证服务器创建的。

5 为什么jwt中推荐使用RSA-256而不是HS-256

原因:

  1. 最重要的原因是使用RSA-256能简化公钥的分发过程
  2. RSA中加密的私钥只有认证服务器拥有,即使公钥丢失,黑客除了解密数据之外无法伪造数据
  3. 根据盗来的JWT Header和Payload生成SHA-256哈希值,之后他还要暴力破解RSA才能继续生成签名。

(还记得之前我们说过,用来校验token的公钥可以随意分发,黑客无法使用它来做任何有意义的事情。然而黑客并不是想校验token,他们只是想伪造它们。这就使得我们将公钥放置到受我们自己控制的服务器上成为可能,应用服务器连接到公钥放置的服务器获取公钥,然后定期检查公钥是否有变化。因此,在更新密钥时,应用服务器和认证服务器不需要同时暂停服务。)

6 jwt在企业中的应用

JWT同样适用于企业内部,替代经典的存在已知安全隐患的预身份验证设置(Pre-Authentication setup)方式。

预身份验证设置方式中,我们的应用服务器在私有网络的一个代理后面运行,然后从HTTP请求头中获取当前用户信息。代表用户身份的HTTP请求头通常由中心化的登录页面填充,同时中心化的节点也对用户session进行管理。

当session过期后,服务器将阻止对应用的访问,并要求用户重新登录认证。之后,它将所有请求转发到应用服务器并在HTTP请求头添加代表用户身份的信息。

问题是这种设置方式,内网上的任何人都可以假扮成某个用户,只要设置同样的HTTP请求头。

对此也有一些解决方案,比如白名单列表,或者某种客户凭证。

  • 更好的预身份验证设置方式

预身份验证设置方式是一个好主意,毕竟这种方式可以使得应用开发者不需要实现认证逻辑,减少开发时间和潜在的安全问题。

如果能有预身份验证设置方式的便捷,又没有安全方面的妥协,岂不美哉?

如果我们考虑到JWT,则可以轻松做到。我们不像以往那样将用户名放到HTTP请求头,而是将HTTP请求头封装成一个JWT。我们将用户名放到Payload里面,再由认证服务器加签。

应用服务器不再从HTTP请求头获取用户名,而是首先校验JWT:

  1. 如果签名是正确的,则用户认证通过,请求可以放行;
  2. 否则,应用服务器简单的拒绝请求就好了;

这样的结果就是,即使在私有网络内,我们的认证功能也可以正常工作。我们再也不需要通过HTTP请求头来识别用户了,我们保证了HTTP请求头的有效性并且是由代理生成的,而不是某黑客试图以某个用户身份登录。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值