架构安全性
认证
系统正确分辨出操作用户的真实身份
授权
系统控制一个用户该看到哪些数据、能操作哪些功能
-
确保授权的过程可靠:OAuth2
-
确保授权的结果可控:RBAC 基于角色的访问控制 Role-Based Access Control
谁(User)拥有什么权限(Authority)去操作(Operation)哪些资源(Resource)
RBAC
-
在用户对象上设定一些权限,当用户使用资源时,检查是否有对应的操作权限即可。
-
将权限从用户身上剥离,改为绑定到“角色”(Role)上,将权限控制变为对“角色拥有操作哪些资源的许可”这
OAuth2
面向于解决第三方应用的认证授权协议。
以令牌(Token)代替用户密码作为授权的凭证。有了令牌之后,哪怕令牌被泄漏,也不会导致密码的泄漏;令牌上可以设定访问资源的范围以及时效性;
凭证
单体 :以 HTTP 协议的 Cookie-Session 机制为代表的服务端状态存储
分布式系统: JWT
Cookie-Session
HTTP 协议是一种无状态的传输协议,无状态是指协议对事务处理没有上下文的记忆能力,每一个请求都是完全独立的
让服务器至少有办法能够区分出发送请求的用户是谁
在 HTTP 协议中增加了 Set-Cookie 指令,该指令的含义是以键值对的方式向客户端发送一组信息,此信息将在此后一段时间内的每次 HTTP 请求中,以名为 Cookie 的 Header 附带着重新发回给服务端,以便服务端区分来自不同客户端的请求。
Set-Cookie: id=icyfenix; Expires=Wed, 21 Feb 2020 07:28:00 GMT; Secure; HttpOnly
GET /index.html HTTP/2.0
Host: icyfenix.cn
Cookie: id=icyfenix
在 Cookie 中传输也并不安全,容易被中间人窃取或被篡改
Session
一般来说,系统会把状态信息保存在服务端,在 Cookie 里只传输的是一个无字面意义的、不重复的字符串,习惯上以sessionid
或者jsessionid
为名,服务器拿这个字符串为 Key,在内存中开辟一块空间,以 Key/Entity 的结构存储每一个在线用户的上下文状态,再辅以一些超时自动清理之类的管理措施。
优点:
-
状态信息都存储于服务器,只要依靠客户端的
-
服务端有主动的状态管理能力,可根据自己的意愿随时修改、清除任意上下文信息,譬如很轻易就能实现强制某用户下线的这样功能。
JWT JSON Web Token
JWT是Cookie-Session 在认证授权问题上的替代品。
无法携带大量信息。
JWT 明文传输,只解决防篡改的问题,并不解决防泄漏的问题。
JWT结构分为三部分:
-
令牌头Header
{
"alg": "HS256",
"typ": "JWT"
}描述了令牌的类型(统一为 typ:JWT)以及令牌签名的算法
-
负载
向服务端传递的信息,认证—>“这个用户是谁”,授权—>"这个用户拥有什么角色/权限”
{
"username": "icyfenix",
"authorities": [
"ROLE_USER",
"ROLE_ADMIN"
],
"scope": [
"ALL"
],
"exp": 1584948947,
"jti": "9d77586a-3f4f-4cbb-9924-fe2f77dfa33d",
"client_id": "bookstore_frontend"
}-
iss(Issuer):签发人。
-
exp(Expiration Time):令牌过期时间。
-
sub(Subject):主题。
-
aud (Audience):令牌受众。
-
nbf (Not Before):令牌生效时间。
-
iat (Issued At):令牌签发时间。
-
jti (JWT ID):令牌编号。
-
-
签名
使用在对象头中公开的特定签名算法,通过特定的密钥(Secret,由服务器进行保密,不能公开)对前面两部分内容进行加密计算
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload) , secret)
确保负载中的信息是可信的、没有被篡改的,也没有在传输过程中丢失任何信息。
JWT缺点:
-
令牌难以主动失效
需要设计一个“黑名单”的额外的逻辑,用来把要主动失效的令牌集中存储起来,而无论这个黑名单是实现在 Session、Redis 或者数据库中,都会让服务退化成有状态服务,降低了 JWT 本身的价值
-
相对更容易遭受重放攻击
-
只能携带相当有限的数据
保密
保证敏感数据无法被包括系统管理员在内的内外部人员所窃取、滥用
强度
-
以摘要代替明文:弱密码会被彩虹表攻击所破解
-
先加
-
将盐值变为动态值能有效防止冒认,难以阻止对其他服务的
-
动态令牌,在网关或其他流量公共位置建立校验逻辑。防止重放攻击,但是依然不能抵御传输过程中被嗅探而泄漏信息的问题。
-
启用 HTTPS 可以防御链路上的恶意嗅探,也能在通信层面解决了重放攻击的问题。
客户端加密
为了保证信息不被黑客窃取而做客户端加密没有太多意义,对绝大多数的信息系统来说,启用 HTTPS 可以说是唯一的实际可行的方案。
为了保证密码不在服务端被滥用,在客户端就开始加密是很有意义的。抵御拖库
密码存储和验证
加密
-
客户端对用户密码进行简单哈希摘要
client_hash = MD5(password)
-
客户端加盐
client_hash = MD5(MD5(password) + salt)
-
为了抵御攻击者截获了客户端发出的信息,得到了摘要结果和采用的盐值,引入慢哈希函数来解决
慢哈希函数一般在客户端使用,服务端使用会占用大量计算器资源
慢哈希函数:函数执行时间是可以调节的哈希函数,通常是以控制调用次数来实现的。
client_hash = BCrypt(MD5(password) + salt)
-
防御被拖库后针对固定盐值的批量彩虹表攻击。具体做法是为每一个密码(指客户端传来的哈希值)产生一个随机的盐值。
-
将动态盐值混入客户端传来的哈希值再做一次哈希,产生出最终的密文,并和上一步随机生成的盐值一起写入到同一条数据库记录中
解密
-
接受到客户端传输上来的哈希值,从数据库中取出登录用户对应的密文和盐值,采用相同的哈希算法,对客户端传来的哈希值、服务端存储的盐值计算摘要结果。
-
和数据库储存的哈希值比较是否相同
传输
保证通过网络传输的信息无法被第三方窃听、篡改和冒充
摘要
在源信息不泄漏的前提下辨别其真伪
不可逆
加密
加密是可逆的,逆过程就是解密
对称加密,有密钥
非对称加密,公钥私钥,互相解密
HTTPS结合对称与非对称加密,非对称传输对称的密钥。
签名方面:以对摘要结果做加密的形式来保证签名的适用性。
数字证书
保证公钥可信分发的标准,PKI
CA:负责发放和管理数字证书的权威机构
客户的机器上已经预置了这些权威 CA 中心本身的证书(称为 CA 证书或者根证书),使得我们能够在不依靠网络的前提下,使用根证书里面的公钥信息对其所签发的证书中的签名进行确认。
数字证书包含内容:
-
版本号
-
序列号(Serial Number): 由证书颁发者分配的本证书的唯一标识符。
-
签名算法标识符(Signature Algorithm ID)
-
认证机构的数字签名(Certificate Signature)
-
认证机构(Issuer Name)
-
有效期限(Validity Period)
-
主题信息(Subject):证书持有人唯一的标识符(Distinguished Name),这个名字在整个互联网上应该是唯一的,通常使用的是网站的域名。
-
公钥信息(Public-Key): 包括证书持有人的公钥、算法(指明密钥属于哪种密码系统)的标识符和其他相关的密钥参数
传输安全层 TLS
传输之前的握手过程一共需要进行上下两轮、共计四次通信
验证
确保提交到每项服务中的数据是合乎规则的,不会对系统稳定性、数据一致性、正确性产生风险
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构