随笔 - 807  文章 - 0 评论 - 143 阅读 - 770万

数字签名的意义,看下百科:数字签名sign可不是对数据的加密和解密,而是生成签名和验证签名

https://baike.baidu.com/item/%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D%E7%AE%97%E6%B3%95/12724298

 

 

================================

1. 我肯定不会使用对称秘钥的签名,因为对称秘钥,开发者可以知道秘钥了,安全意义有限,且对称秘钥的签名没有意义,因为直接用对称秘钥加密就可以了,再搞个签名没有意义。

所以接下来主要是讨论“非对称秘钥的签名”;

我自己设计的token与 jwt的不同,jwt的头部签名算法声明,有点啰嗦没有必要,因为我们自己开发的项目不可能多少token的颁发处,多种签名算法,那样反而会乱七八糟,所以我去除了jwt的头部,

我自己设计的token只包含2部分,payload部分 + 签名 部分;

首先要理解 签名算法 与 aes 和 rsa加密算法 是不同的,不要搞混淆。

aes我通常使用 aes128 加解密。

RSA我通常使用默认的加解密。

签名算法有很多,jdk8官方的api文档如下:

 

 

 

 

 

 

 

 

 

 

通常签名算法,推荐使用:SHA256withRSA

 

 

 

 

 

知道了java支持的签名算法之后,再去看下  jwt,jwt就是头部算法声明 + payload + 签名来组成,jwt为了 简化头部的字符串占用,简化了名称,我们看下 jwt的签名算法 支持:

 

加密方式 支持情况 全称 
 HS256  ✔  HMAC with SHA-256
 HS384  ✔  HMAC with SHA-384
 HS512  ✔  HMAC with SHA-512
 PS256  ✖  RSAPSS with SHA-256
 PS384  ✖  RSAPSS with SHA-384
 RS256  ✔  RSAPSS with SHA-512
 RS384  ✔  RSASSA-PKCS1-v1_5 with SHA-256
 RS512  ✔  RSASSA-PKCS1-v1_5 with SHA-384
 ES256  ✔  RSASSA-PKCS1-v1_5 with SHA-512
 ES256K  ✔  ECDSA with curve P-256 and SHA-256
 ES384  ✔  
 ES512  ✔  ECDSA with curve P-384 and SHA-384
 EdDSA  ✖  Edwards-curve DSA

 

 

 

 

三、算法加密方式简介

在比较签名算法之前,需要先了解一下原理,对算法有基本认知,便于测试预期。

3.1 SHA简介 

SHA-2是一种散列算法(哈希函数),细分了6个算法标准,SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256,他们的差异大概是一些生成摘要长度、循环运行次数等。 

3.2 HMAC简介

HMAC(Hash-based Message Authentication Code)是对称加密,加密和解密用的是相同的密钥,主要用于消息防篡改,哈希算法可以选择md5、sha1、sha2(sha256,sha385,sha512)。 

 

 

  • 如果密钥比分组长度短,则末尾填充0直到达到分组长度;如果密钥比分组长度还长,则会用哈希计算出密钥的散列值,然后让这个散列值作为HMAC的密钥,散列长度一般仍然小于分组长度,所以散列之后仍然要填充0。 
  • 如果是SHA-1或SHA-256,则分组长度为64;如果是SHA-384和SHA-512。 
  • 密钥长度如果小于哈希输出数据字长(SHA-256输出256位,所以为32,384为48,512为64),则加密效果不佳,如果超出这个长度,并不能带来显著的安全强度提升。 

另外,从官方jwt.io的网页推荐可以看出,也是希望使用和哈希函数匹配的长度(your-256-bit-secret):

 

 

3.3 RSA相关简介

RSA是非对称加密,算法运行较慢。RSA没有加入随机数,因此如果攻击者遍历猜测所有的原文,可以通过对比相同的加密密文选择出真实原文,为了防止这种情况,RSA加入了padding机制,对数据进行填充。 

 

 

RSA主流的签名模式为RSA-PSS(Probabilistic Signature Scheme)和RSA-PCKS#1_v1.5(Public Key Cryptography Standards),PSS是私钥签名的填充模式(padding mode),相对而言这种方式更加安全,openssl-1.1.x以后(server key exchange阶段)默认使用PSS填充。 

发送方加密并不是对数据直接进行加密,而是通过SHA等散列函数对数据内容进行哈希之后,再对这个哈希值用公钥进行加密。接收方同样对内容计算SHA散列函数哈希值,然后用私钥解开加密的哈希值,比对两个哈希值是否一致,如果一致则说明数据内容没有被篡改过。 

如果业务上面只是自己签发自己验证JWT,公钥私钥都存放在同一个地方,从便利性角度而言和HMAC没有差异。

RSA有个选项是“密钥位数”,有512、1024、2048、4096等,尽管公私钥都是存在服务器的,但为了防止暴力猜测破解,仍然使用1024位以上比较安全。 

 

此博主最终的结论:

4.2.6 列表比较

 比较项  考虑因素  结论 
 签名长度  使用方的内存占用  HS、ES可以接受,RS过长
 生成速度  频繁生成JWT的业务  HS最快,RS和ES接近
 校验速度  频繁校验JWT的业务  HS最快,RS略慢,ES很慢
 生成CPU  对CPU资源有要求  HS最少,RS、ES都较多,RS略少于ES
 校验CPU  对CPU资源有要求   HS和RS都很少,ES较多

4.3 优缺点和适用场景

(1)HS256 / HS384 / HS512

优点:速度快、生成校验CPU少、签名位数少

缺点:对称加密,密钥泄漏影响大;不适合多服务校验场景

注意:密钥位数的提高并不能显著提高安全性。

(2)RS256 / RS384 / RS512

优点:校验速度可以接受、安全等级高、适合多服务校验场景

缺点:CPU消耗较大,生成速度较慢(但生成一般都是低频率事件),签名位数多(有嵌入式设备一定要注意了)

(3)ES256 / ES256K / ES384 / ES512

优点:安全等级高、适合多服务校验场景

缺点:CPU消耗严重(对普通应用不划算的)、生成和校验速度较慢,尤其是校验速度

【推荐方案选择】

普通应用推荐使用HS,并且定期轮换密钥避免对称性加密密钥泄漏的风险;

较为复杂的应用可用RS

安全应用可用ES

 

posted on   del88  阅读(991)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
历史上的今天:
2020-07-09 electron、nodejs、typescript、idea 组合开发,安装和配置 以及错误 等 详细说明
2020-07-09 npm i -D和-s及-g以及--save的那些事
2016-07-09 IntelliJ IDEA 启动方法
2016-07-09 修改VNCSERVER 默认的分辨率的方法
2016-07-09 Xshell 找到上次执行的命令
点击右上角即可分享
微信分享提示