文章目录
OverView
即使只限定在"软件架构设计"这个语境下,系统安全仍然是一个很大的话题。
接下来我们将对系统安全架构的各个方面进行详细分析,包括认证、授权、凭证、保密、传输安全和验证,结合案例实践,展示如何应用这些安全原则和技术,讨论具体解决方案和行业标准 ,并提供与业界标准相一致的解决方案。
计划:
-
认证(Authentication):
- 介绍认证的基本概念及其在软件架构中的作用。
- 讨论常见的认证方法(如用户名/密码、双因素认证、生物识别)及其实现方式。
- 探讨行业标准和最佳实践(如 OAuth、OpenID Connect)。
-
授权(Authorization):
- 定义授权的概念及其重要性。
- 讲解不同的授权模型(如基于角色的访问控制RBAC、基于属性的访问控制ABAC)。
- 介绍如何在架构中实现这些模型以及如何处理权限管理。
-
凭证(Credential):
- 阐明凭证的作用及其管理方式。
- 讨论如何确保证书和凭证的真实性、完整性和不可抵赖性。
- 介绍现有的凭证管理方案和技术(如 PKI、公钥基础设施)。
-
保密(Confidentiality):
- 解释数据保密的基本概念及其在系统中的应用。
- 讨论数据加密的技术和策略(如对称加密、非对称加密)。
- 介绍如何确保保密性,包括数据存储和处理中的加密措施。
-
传输(Transport Security):
- 定义传输安全及其对系统安全的影响。
- 讲解如何实现传输层安全(如 TLS/SSL)的具体方法。
- 讨论如何保护网络通信免受中间人攻击和数据篡改。
-
验证(Verification):
- 介绍数据验证的必要性及其对系统稳定性的影响。
- 讨论常见的验证技术(如输入验证、数据完整性检查)。
- 讲解如何在系统中实现数据验证机制以保证数据一致性和正确性。
认证的标准
认证(Authentication)是系统安全中的一个核心概念,用于确定操作用户的真实身份。认证不仅涉及到用户登录,还包括系统如何管理和保护用户的身份信息。
认证的基础
在系统中,认证、授权和凭证是最基础的安全设计。
- 认证回答"你是谁?"的问题,
- 授权回答"你能干什么?"的问题,
- 凭证则回答"你如何证明?"的问题。
这三者通常紧密结合在一起,用以保证系统的安全性。
认证的范围
虽然认证通常首先让人联想到用户登录,但实际上,认证对象不仅可以是人,还可以是外部的代码或服务。在早期的Java系统中,代码级安全认证甚至比用户级安全认证更为重要。
这一阶段的安全观念催生了现在仍然存在于 Java 技术体系中的"安全管理器"(java.lang.SecurityManager)、"代码权限许可"(java.lang.RuntimePermission)等概念
现代系统中,代码认证通常通过证书签名实现,而最终用户的认证则涉及到更加复杂的机制。
认证的标准与实践
在网络和Web应用的背景下,认证通常分为以下三种层次:
- 通信信道上的认证:在建立通信连接之前,验证通信双方的身份,例如基于SSL/TLS的认证。
- 通信协议上的认证:在请求资源之前,验证请求者的身份,例如基于HTTP(S)协议的认证。
- 通信内容上的认证:在使用服务之前,验证使用者的身份,例如基于Web内容的认证。
HTTP认证框架
HTTP认证框架通过定义认证方案(Authentication Schemes
)来生成身份凭证。服务器在未授权的用户尝试访问资源时,会返回一个401状态码,并附带指示认证方案的WWW-Authenticate
头。客户端随后使用Authorization
头发送凭证信息。
常见的认证方案包括:
-
Basic认证:通过Base64编码的用户名和密码进行认证,简单但不安全。
Basic 认证产生用户身份凭证的方法是让用户输入用户名和密码,经过 Base64 编码"加密"后作为身份凭证。
譬如请求资源GET /admin后,浏览器会收到来自服务端的如下响应:
javaHTTP/1.1 401 Unauthorized Date: Mon, 24 Feb 2020 16:50:53 GMT WWW-Authenticate: Basic realm="example from icyfenix.cn"
此时,浏览器必须询问最终用户,即弹出 HTTP Basic 认证对话框,要求提供用户名和密码。.
用户在对话框中输入密码信息, 浏览器会将字符串icyfenix:123456编码,然后发送给服务端,HTTP 请求如下所示:
javaGET /admin HTTP/1.1 Authorization: Basic aWN5ZmVuaXg6MTIzNDU2
服务端接收到请求,解码后检查用户名和密码是否合法,如果合法就返回/admin的资源,否则就返回 403 Forbidden 错误,禁止下一步操作。注意 Base64 只是一种编码方式,并非任何形式的加密,所以 Basic 认证的风险是显而易见的。
除 Basic 认证外,IETF 还定义了很多种可用于实际生产环境的认证方案,列举如下
- Digest认证 : RFC 7616 改进了Basic认证,使用哈希算法加密凭证,但仍然存在安全风险。 HTTP 摘要认证,可视为 Basic 认证的改良版本,针对 Base64 明文发送的风险,Digest 认证把用户名和密码加盐(一个被称为 Nonce 的变化值作为盐值)后再通过 MD5/SHA 等哈希算法取摘要发送出去。但是这种认证方式依然是不安全的,无论客户端使用何种加密算法加密,无论是否采用了 Nonce 这样的动态盐值去抵御重放和冒认,遇到中间人攻击时依然存在显著的安全风险。
- Bearer认证 : RFC 6750 基于OAuth2协议,涉及认证与授权。
- HOBA : RFC 7486 HOBA(HTTP Origin-Bound Authentication)是一种基于自签名证书的认证方案。基于数字证书的信任关系主要有两类模型:一类是采用 CA(Certification Authority)层次结构的模型,由 CA 中心签发证书;另一种是以 IETF 的 Token Binding 协议为基础的 OBC(Origin Bound Certificate)自签名证书模型
Web认证(表单认证)
相比于HTTP认证框架,Web认证更加灵活和常用,尤其是在Web应用中。表单认证允许开发者设计不同的登录界面,并提供各种认证方式。尽管表单认证的实现方式多样,但在安全性上,仍需遵循标准的安全实践。
WebAuthn标准
WebAuthn是由W3C批准的Web内容认证标准,通过生物识别或实体密钥替代传统的密码登录。它采用公钥/私钥对的方式进行认证,私钥存储在用户设备上,极大提升了安全性。
认证流程示例:WebAuthn
注册流程:
- 用户访问注册页面并提交信息。
- 服务器生成随机字符串(Challenge)和用户ID(UserID),返回给客户端。
- 客户端通过WebAuthn API与验证器(如指纹识别设备)通信,生成密钥对并返回签名结果和公钥。
- 服务器核验信息并存储公钥。
登录流程:
- 用户访问登录页面并输入用户名。
- 服务器返回Challenge和UserID。
- 客户端与验证器通信,使用私钥签名Challenge。
- 服务器使用公钥验证签名,确认用户身份。
WebAuthn 采用非对称加密的公钥、私钥替代传统的密码,这是非常理想的认证方案,私钥是保密的,只有验证器需要知道它,连用户本人都不需要知道,也就没有人为泄漏的可能;公钥是公开的,可以被任何人看到或存储。公钥可用于验证私钥生成的签名,但不能用来签名,除了得知私钥外,没有其他途径能够生成可被公钥验证为有效的签名,这样服务器就可以通过公钥是否能够解密来判断最终用户的身份是否合法。
WebAuthn 还一揽子地解决了传统密码在网络传输上的风险, 因为无论密码是否客户端进行加密、如何加密,对防御中间人攻击来说都是没有意义的。更值得夸赞的是 WebAuthn 为登录过程带来极大的便捷性,不仅注册和验证的用户体验十分优秀,而且彻底避免了用户在一个网站上泄漏密码,所有使用相同密码的网站都受到攻击的问题,这个优点使得用户无须再为每个网站想不同的密码
小结
认证在系统安全中扮演着关键角色,从简单的HTTP认证到复杂的WebAuthn标准,认证机制的选择和实现都应考虑安全性和实际需求。在设计和实现认证系统时,遵循已有的标准和最佳实践是确保系统安全的有效途径。
认证的实现
JAAS
Java 技术体系内的认证实现经历了多个阶段,从早期的 JAAS 到现代的 Spring Security 和 Shiro。
1. JAAS(Java Authentication and Authorization Service)
JAAS 是 Java 1.3 引入的一种安全框架,旨在提供统一的认证和授权服务。它的设计目标是为代码级安全和用户级安全提供支持。JAAS 引入了许多关键概念,这些概念在现代 Java 安全框架中依然活跃:
- LoginModule:负责实现具体的认证逻辑。
- LoginContext:用于管理认证过程,协调多个 LoginModule 的执行。
- Subject:代表了经过认证的实体,如用户。
- Principal:代表特定实体的标识信息,如用户名。
- Credentials:存储敏感信息,如密码或密钥。
虽然 JAAS 引入了这些概念,但由于其复杂性和较高的学习曲线,它并未得到广泛应用,尤其是在 Java 社区向轻量级开发框架的转变过程中。
Spring Security 和 Shiro
2. 现代 Java 安全框架中的认证
在现代 Java 开发中,Apache Shiro 和 Spring Security 是最常用的认证框架。它们在设计上更注重简化开发者的工作,同时提供强大的功能。
-
Apache Shiro:相对简洁易用,适合中小型应用。它通过简单的配置即可实现用户认证、授权和会话管理。
-
Spring Security:功能强大,特别适合与 Spring 生态系统集成。Spring Security 提供了丰富的认证选项,如基于表单的认证、OAuth2、JWT 等,同时还支持复杂的权限管理和自定义扩展。
两者在功能上非常相似,主要提供以下功能:
- 认证功能:验证用户身份,支持多种认证方式。
- 安全上下文:管理认证后的用户信息和权限。
- 授权功能:控制用户对资源的访问权限。
- 密码存储与验证:提供安全的密码管理机制。
小结
JAAS 开创了许多重要的安全概念,这些概念在今天仍然活跃于现代 Java 安全框架中。然而,由于其复杂性和与轻量级框架的竞争,JAAS 并未成为主流。取而代之的是更易用且功能强大的 Apache Shiro 和 Spring Security,它们在现代 Java 应用中扮演着至关重要的角色。