数字签名的意义,看下百科:数字签名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
本文来自博客园,作者:del88,转载请注明原文链接:https://www.cnblogs.com/del88/p/16460608.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享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 找到上次执行的命令