数据动态安全协议综述

简单罗列,每个协议的使用不管,需要一定背景知识

Posted by xuefly on August 16, 2020

数据安全一般分为动态的安全,静态安全.

静态安全主要是指存储状态的安全,如加密、使用前的脱敏等。 而动态安全是指在请求数据访问时的安全。 主要作用于两个阶段:

  • 请求的客户端/服务端的身份认证
  • 数据在传输过程中的保密和完整性

本文主要涉及动态安全,自己画的各个协议的关系图: 安全协议

HTTPS

SSL(Secure Socket Layer 安全套接层)是基于HTTPS下的一个协议加密层,最初是由网景公司(Netscape)研发,后被IETF(The Internet Engineering Task Force - 互联网工程任务组)标准化后写入(RFCRequest For Comments 请求注释),RFC里包含了很多互联网技术的规范!

起初是因为HTTP在传输数据时使用的是明文(虽然说POST提交的数据时放在报体里看不到的,但是还是可以通过抓包工具窃取到)是不安全的,为了解决这一隐患网景公司推出了SSL安全套接字协议层,SSL是基于HTTP之下TCP之上的一个协议层,是基于HTTP标准并对TCP传输数据时进行加密,所以HPPTS是HTTP+SSL/TCP的简称。

由于HTTPS的推出受到了很多人的欢迎,在SSL更新到3.0时,IETF对SSL3.0进行了标准化,并添加了少数机制(但是几乎和SSL3.0无差异),标准化后的IETF更名为TLS1.0(Transport Layer Security 安全传输层协议),可以说TLS就是SSL的新版本3.1,并同时发布“RFC2246-TLS加密协议详解”,如果想更深层次的了解TLS的工作原理可以去RFC的官方网站:www.rfc-editor.org,搜索RFC2246即可找到RFC文档!

所以使用 HTTPS 必然用使用 SSL/TSL 的.

SSL

我们知道, 传统的加密技术有2个类型, 一个是对称加密(例如DES) , 另一个是非对称加密(例如RSA).

其中非对称加密中有私钥和公钥的概念, 十分适合验证特定对象的真实性和唯一性. 但非对称加密算法比较复杂, 速度缓慢 , 也很消耗资源, 因此就不适合大数据量的加密.

而对称加密由于两端同用一组密码,加密和解密算法比较简单, 适合大数据量加密.

SSL全称是 Secure Sockets Layer,它是一种间于传输层(比如TCP/IP)和应用层(比如HTTP)的协议. 它通过”握手协议”和”传输协议”来解决传输安全的问题.

SSL的基本思想是用非对称加密来建立链接(握手阶段),用对称加密来传输数据(传输阶段)。这样既保证了密钥分发的安全,也保证了通信的效率(因为非对称加密更耗时)。

握手协议是基于非对称加密的,而传输协议是基于对称加密的。根据不同的应用,SSL对证书的要求也是不一样的,可以是单方认证(比如HTTP, FTP),也可以是双方认证(比如网上银行)。通常情况下,服务器端的证书是一定要具备的,客户端的证书不是必须的。

传输过程: 在通信双方协商出一个对称密钥以后,他们用这个密钥来加密传输的数据。同时为每个消息生成时间戳,用此密钥为消息和相应的时间戳生成消息认证码(MAC)。也就是说,每次发送的内容包括 Encrypt(message) + MAC(message + timestamp)

好处

  1. 防止消息的篡改 所谓消息篡改就是有第三者插在通信双方之间,篡改往来的消息。由于消息是加密的,第三者不能获得消息的内容,但是他可以闭着眼睛瞎改。如果没有MAC的话,接受者就无法判断此 消息是否被篡改过。
  2. 防止消息重放 消息的重放是只第三者记录下通信双方的每一次发送的消息,虽然他不能获得消息的内容。但是它可以通过重新发送客户端或者服务端的信息来把自己装成是客户端或者服务端。如果在MAC里面加上了时间戳,消息接收方验证时间戳就可以阻止消息的重放攻击。

SSL的基本思想是用非对称加密来建立链接(握手阶段),用对称加密来传输数据(传输阶段)。这样既保证了密钥分发的安全,也保证了通信的效率

SASL

sasl:是作用在认证层上,是一种身份认证框架,sasl验证架构决定服务器本身如何存储客户端的身份证书以及如何核验客户端提供的密码。 SASL是一种用来扩充C/S模式验证能力的机制认证机制, 全称Simple Authentication and Security Layer.

如果客户端能成功通过验证,服务器端就能确定用户的身份, 并借此决定用户具有怎样的权限。

sasl的常见具体实现有plain、kerberos等, 就好比slf4j是框架,log4j是具体实现

如果要将Kerberos与SASL一起使用,则将需要另一种间接级别:GSSAPI(最常与Kerberos一起使用,但也可以允许其他机制)。

SSL和SASL之间的一个明显区别是,SASL允许选择不同的机制来对客户端进行身份验证,如可以选择使用GSSAPI,Kerberos,NTLM等, 而SSL被绑定为基于证书进行身份验证。

Kerberos

Kerberos本身是一个协议.

Kerberos协议的认证过程比较难懂,即便是看别人的理解后的解释文档,这反映了文字表达的局限性,另外需要对对称加密和非对称加密有了解. 下面这篇稍微好一点. 图解Kerberos协议

读后可以发现:Kerberos 认证协议依赖于使用共享密钥和密码提示的对称认证。在认证过程的不同阶段,不同的拓扑成员需要对令牌进行加密或解密。通常,Kerberos 不限制所使用的加密算法。管理员必须知道不同拓扑成员使用的加密算法。

多家厂商对这个协议进行实现. 比如 MIT 微软 苹果 谷歌等等.

GSS-API

从名字Generic Security Services Application Program Interface,即:通用安全服务的应用程序接口,可以看出, GSS-API是一个 API 规范,是在具体实现 Kerberos 协议时的 定义的API.

The dominant GSSAPI mechanism implementation in use is Kerberos. Unlike the GSSAPI, the Kerberos API has not been standardized and various existing implementations use incompatible APIs. The GSSAPI allows Kerberos implementations to be API compatible.

意思就是:有了这个规范,只要各个厂商按照这个规范实现 Kerberos,就至少可以做到一个客户端可以可以连接不同厂商的 KDC 服务,相反一个服务端可以连接不同实现方式的客户端.

总结下来就是:Kerberos是一帮数学密码学家从理论上搞出来的认证协议,GSS-API是一帮 IT 架构师设计的实现这个协议的程序接口,而 MIT Kerberos Windows AD等各个厂商通过安装GSS编码,做到了 API 的兼容.

JAAS

JAAS,是用于处理身份验证和授权的通用Java框架

比如在部署的服务中看到类似这样的配置文件jaas.conf

KafkaServer {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/opt/third/kafka/kerberos/kafka_server.keytab"
    principal="kafka/stream.dt.local@EXAMPLE.COM";
};
# 此context名字为ZKClient,对应kafka broker启动参数-Dzookeeper.sasl.client=ZkClient
ZkClient {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/opt/third/kafka/kerberos/kafka_server.keytab"
    principal="kafka/stream.dt.local@EXAMPLE.COM";
};

Java密钥库(KeyStore)

简介

Java的密钥库用于存储与部署X509证书和私钥。Java密钥库是JavaSE的中的特性。 Sun的JDK提供了标准的基于文件实现的密钥库.

密钥库提供者

公钥和私钥都可以称之为密钥.

翻开jdk安装目录,在java/lib/security或者java/jre/lib/security 你会发现java.security文件,其中有一项定义: keystore.type=jks jks类型代表的是java的标准密钥库格式 Java允许你可以提供定制化的密钥库实现,通过实现java.security.keystoreSpi类即可 如果你使用的是一个定制化的密钥库提供者,你应该阅读第三方的定制文档,了解在此定制环境下怎样管理证书和私钥。

库密码

密钥库由密码进行保护,该密码在创建密钥库的时候创建的,每次当你企图访问或修改密钥库的时候,你必须提供这个密码。 库密码可能指密钥库,也可能指信任库,这取决于你把何种条目存储在库中。但两种情况下的作用是一样的:解锁库文件。 默认是:changeit

密钥库条目

有两种条目可以被存放在密钥库中,分别是证书和密钥

  1. 密钥条目,每个密钥条目包含下列组件
    • 私钥
    • X509证书(可以是v1,v2,v3),证书中含有与此私钥条目相匹配的公钥
    • 可选,一个或多个该证书链上的CA根证书, 属于该证书链上的CA根证书,可以放在密钥条目下,也可以放在可信证书条目下。 此外,每一个密钥条目都有一个别名作为标签,并且有密码保护,要想访问特定的密码条目,你必须同时提供别名和密码才行。
  2. 可信证书条目,每个可信证书条目只包含有一个X509证书 每个可信证书条目也用别名作为标签,但没有必要用密码保护,因为X509证书中只有公钥没有私钥。

    我在部署 presto 的时候首先添加的就是 ldap 服务器的证书.

处理密钥库的工具

在JavaSE中提供了两个工具:keytool和jarsigner