mozilla的安全架构

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:
mozilla在安全方面主要分为三大块:1.SSL协议的实现;2.Crypto库的实现;3.PKCS#11的实现最顶层是ssl的实现,和openssl不同,mozilla是自上而下设计的,因此mozilla并没有抽象出诸如BIO或者EVP之类的通用机制,可以它实现了一个PRFileDesc结构体,和BIO是很类似的;涉及到安全的实现就是2和3了,其中3定义了接口,2给与了软实现,当然你可以加载plugin使用硬件实现。三者合一形成了mozilla的安全架构。
     有几个重要的结构体先了解一下:sslSocketStr结构和openssl中的ssl_st结构体非常类似:
struct sslSocketStr {
        PRFileDesc *    fd;  //一个文件IO分发表,类似linux内核的file_operations,仅仅作为接口定义。
        const sslSocketOps * ops //实现PRFileDesc的接口定义;  
    ...
    sslSecurityInfo  sec; //操作ssl信道的方式,比如加密,解密之类
    ...
        const char      *url;    //目的地址,浏览器接受的url
    ...
    sslHandshakeFunc handshake;        //函数可以作为锁来使用
    sslHandshakeFunc nextHandshake;                
    sslHandshakeFunc securityHandshake;    
      //回调函数,timeout,lock,暂存缓冲,线程,ssl握手方法,状态
};
上面的一个sslSocketStr代表了一个连接,并且描述了表示层即ssl协议,和openssl类似,mozilla也永术语“PUSH”来将一个安全描述符压入一个普通的传输层套接字(类似OpenSSL的BIO机制,后面会说),比如你访问http://www.google.com.hk,那么敲下回车的时候就会建立一个sslSocketStr,其中url就是你要访问的google的网址,某些网站需要安全连接,如果需要安全的话随之就会初始化sslSocketStr中的fd中的PRIOMethods为ssl_methods,它完成了套接字IO的几乎所有的语义,在openssl中,该结构体由SSL_METHOD实现,原理和此处的mozilla几乎一致:
static const PRIOMethods ssl_methods = {
    PR_DESC_LAYERED,
        ...
    ssl_Read,                //read
    ssl_Write,               //write
   ssl_Recv,                //recv
    ssl_Send,                //send
    ...
};
static const sslSocketOps ssl_secure_ops = {
    ...
        ssl_SecureRecv,
        ssl_SecureSend,
        ...
};
为何要有PRIOMethods和sslSocketOps两个结构体呢?看起来一个就够了,答案是为了实现分层模型,PRIOMethods并没有具体的实现策略,只是表示一个“协议层”的语义,对于ssl的具体实现当然没有必要在ssl层就全做掉,因为即使选择ssl也可以有不同的策略,也就需要再来一个结构体了,特别是,这样可以不加区分地统一使用一致的SSL接口,在不实现ssl的情况下,可以再实现一个ssl_default_ops(security/nss/lib/ssl/sslsock.c)。
     ssl_Do1stHandshake完成了ssl握手时的状态机转换,mozilla并不区分client方法和server方法,而是完全按照RFC2246的规定来实现ssl,对于client端,在ssl_SecureConnect中会发起对server的连接,也就是发送一个ClientHello消息,此时会将sslSocketStr的securityHandshake设置为ssl2_BeginClientHandshake(仅对ssl2来说),接下来任何的读写ssl,都会调用PRIOMethods中的recv/send函数,然后就回进入到ssl_Do1stHandshake状态机,在其中client会调用到这个刚刚设置的ssl2_BeginClientHandshake函数,在该函数最后,按照RFC2246的规定,会进行如下设置:
ss->handshake     = ssl_GatherRecord1stHandshake;
ss->nextHandshake = ssl2_HandleServerHelloMessage;
握手回调函数handshake自己维护状态机,这一点和openssl不同,在handshake的调用最后,函数根据调用结果和当前状态将nexthandshake按照RFC2246设置成下一个状态,然后在ssl_Do1stHandshake将状态机向前推进:
int ssl_Do1stHandshake(sslSocket *ss)
{
    do {
        if (ss->handshake == 0) {
            ss->handshake = ss->nextHandshake;
            ss->nextHandshake = 0;
        }
        if (ss->handshake == 0) {
                ss->handshake = ss->securityHandshake;
                ss->securityHandshake = 0;
        }
        ...
        //握手完毕时要退出循环
        rv = (*ss->handshake)(ss); 
        ++loopCount;
        } while (rv != SECFailure);  
        ...
}
ssl握手的后半部分会根据协商内容设置cipher,设置cipher也就部分初始化了sslSocketStr的sec字段,在ssl2_CreateSessionCypher(由状态处理函数ssl2_XYZSetupSessionCypher调用)确定ss->sec.enc函数指针PK11_CipherOp,从此,所有的数据传输都要经过加密,加密的方法就是PK11_CipherOp,mozilla通过封装p11接口来统一处理安全通道的配置以及使用过程。
     PRFileDesc作为一个解耦层(很重要,不仅仅解除了各个模块耦合,而且还实现了一个分层的模型),将操作路由到sslSocketOps,而sslSocketOps中同样可以根据ssl的不同状态或者不同配置将操作继续路由,比如在ssl_SecureSend中会调用:
rv = (*ss->sec.send)(ss, buf, len, flags);
可见sec字段的send也是一个可变更的回调函数,总体的过程就是:
首先ss->fd->methods->send[ssl_Send]:
rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);[ssl_SecureSend]:
rv = (*ss->sec.send)(ss, buf, len, flags);[ssl2_SendBlock]:
ssl_DefSend.
最终ssl_DefSend将数据发送了出去,通过socket将数据发送了出去。

     上述的过程不是很难理解,而且实现的很合理,mozilla更合理的一个地方就是通过PKCS#11接口来统一封装所有的安全操作,为何通过p11封装呢?我觉得p11主要用于客户端,解决了客户端安全加密的一系列问题,而浏览器也在客户端,因此使用p11会十分方便,虽然可能机器上没有usbkey,但是软实现的P11一样好用,毕竟p11只是一个规范,p11的软实现会调用mozilla安全框架的另一部分,那就是crypto接口(类似openssl的EVP)。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271800

相关文章
|
1月前
|
监控 安全 Cloud Native
云原生安全:Istio在微服务架构中的安全策略与实践
【10月更文挑战第26天】随着云计算的发展,云原生架构成为企业数字化转型的关键。微服务作为其核心组件,虽具备灵活性和可扩展性,但也带来安全挑战。Istio作为开源服务网格,通过双向TLS加密、细粒度访问控制和强大的审计监控功能,有效保障微服务间的通信安全,成为云原生安全的重要工具。
48 2
|
2月前
|
Kubernetes 安全 微服务
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
63 8
|
4月前
|
存储 监控 安全
大数据架构设计原则:构建高效、可扩展与安全的数据生态系统
【8月更文挑战第23天】大数据架构设计是一个复杂而系统的工程,需要综合考虑业务需求、技术选型、安全合规等多个方面。遵循上述设计原则,可以帮助企业构建出既高效又安全的大数据生态系统,为业务创新和决策支持提供强有力的支撑。随着技术的不断发展和业务需求的不断变化,持续优化和调整大数据架构也将成为一项持续的工作。
|
4月前
|
Kubernetes 安全 微服务
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
在5G电信领域,Kubernetes集群中部署微服务至关重要,但也带来了重大的安全挑战。Istio作为一个强大的开源服务网格,能有效地管理这些微服务间的通信,通过其控制平面自动将Sidecar代理注入到各微服务Pod中,确保了安全且高效的通信。Istio的架构由数据平面和控制平面组成,其中Sidecar代理作为Envoy代理运行在每个Pod中,拦截并管理网络流量。此外,Istio支持多种Kubernetes发行版和服务,如EKS等,不仅增强了安全性,还提高了应用性能和可观测性。
83 0
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
|
4月前
|
存储 监控 安全
|
4月前
|
存储 安全 关系型数据库
"揭秘!如何设计数据库架构,让信息系统心脏强健无比?一场关于数据效率、安全与可扩展性的深度探索"
【8月更文挑战第19天】数据库架构是信息系统的核心,关乎数据存储效率与安全及应用性能和扩展性。优秀设计需综合考量业务需求、数据模型选择、查询优化、事务处理、安全性和扩展性。首先,深刻理解业务需求,如电商系统需高效处理并增长商品、订单等数据。其次,基于需求选择合适的数据模型,如关系型或非关系型数据库。再者,优化查询性能与索引策略以平衡读写负载。同时,考虑事务处理和并发控制以保证数据一致性和完整性。最后,加强安全性措施和备份恢复策略以防数据风险。通过这些步骤,可以构建稳健高效的数据库架构,支持系统的稳定运行。
50 0
|
5月前
|
安全 Java 数据安全/隐私保护
Spring Boot中的微服务安全架构
Spring Boot中的微服务安全架构
|
6月前
|
SQL 监控 安全
Java中的安全架构设计与实现
Java中的安全架构设计与实现
|
6月前
|
监控 安全 网络安全
探索零信任安全架构:一种现代网络安全策略
零信任安全架构是一种旨在应对现代复杂网络威胁的新型网络安全策略。它的核心理念是“永不信任,始终验证”,即无论内部还是外部的访问请求都需要经过严格的身份验证和授权。在本文中,我们将深入探讨零信任安全架构的基本概念、主要组件及其在实际应用中的优势和挑战。
239 0
|
7月前
|
Cloud Native 安全 云计算
什么是云原生架构,我们该如何做好云原生安全,引领云计算时代的应用程序革新
云原生架构,基于云计算设计理念,强调应用在云环境中设计、构建和运行,利用容器化、微服务、自动化管理和持续交付实现灵活、可扩展和高效。其优势包括高可扩展性、可伸缩性、高效性、灵活性、可靠性和成本效益。应用场景广泛,如电商、金融和物联网。构建关键要素包括容器化、微服务、自动化管理和持续交付。保障安全,需重视容器安全,采用如德迅蜂巢·云原生安全平台等解决方案。云原生正引领应用程序革新,成为现代应用构建首选。