SSL/TLS protocol for vehicle networking communication security

foreword

In today's increasingly intelligent car travel, we can realize the remote control of the mobile phone to unlock the vehicle, start the ventilation, and view the images around the vehicle. We can also use the OTA (over-the-air download technology) to complete operations such as upgrading the car's firmware and updating the map package. It also allows the vehicle to automatically assist in steering, acceleration and braking according to road conditions.

However, every feature that enhances our experience has the potential to become a fatal security hole. Tencent Security Cohen Lab has disclosed and demonstrated to the outside world how to use 3/4G network or WiFi network to invade smart cars without physical contact remotely, and realize remote control of vehicle lights, displays, door locks and even brakes . Not only that, attackers can even exploit a known vulnerability to gain Autopilot control of a smart car and manipulate the direction of the vehicle.

Therefore, we should also fully recognize the importance of communication security, identity authentication, and data security when building the Internet of Vehicles platform, and correctly use relevant encryption authentication and other technical means to provide protection.

In this article, we will comprehensively introduce the application of the SSL/TLS protocol in the communication security of the Internet of Vehicles, hoping to give everyone a clearer and intuitive understanding of the role of SSL/TLS. In addition, we will also explain in detail how to configure SSL/TLS to ensure that you can use SSL/TLS correctly and achieve security.

Internet of Vehicles Safety Communication MQTTS Protocol

The MQTTS protocol is based on the MQTT protocol and encapsulates a layer of encryption protocol based on SSL/TLS (*Transport Layer Security)*, which ensures that the communication between the vehicle terminal and the vehicle networking platform is encrypted. However, if SSL/TLS is not properly configured, there will still be many security risks. To really use SSL/TLS well, we must understand what problems SSL/TLS solves and have a preliminary understanding of the cryptographic techniques used by SSL/TLS.

Typically, a communication process needs to have the following four properties to be considered secure: confidentiality, integrity, authentication, and non-repudiation.

confidentiality

Confidentiality is the foundation of secure communication. Without confidentiality, anyone who eavesdrops on the communication can easily obtain your key private information such as login password and payment password. The most common method to achieve confidentiality is encryption, so that the eavesdropper can only get a meaningless string of encrypted data, and only the person who holds the key can restore the ciphertext to the correct original information. According to the method of using the key, encryption methods can be divided into two types: symmetric encryption and asymmetric encryption. Symmetric encryption means using the same key for encryption and decryption, while asymmetric encryption means using different keys for encryption and decryption.

Symmetric encryption Since both parties use the same key for encryption and decryption, they will inevitably encounter the problem of key distribution, that is, if I need the other party to be able to decrypt the ciphertext I sent in the past, I must use the key I used for encryption. tell the other party, but how can I ensure that the key is not leaked during the synchronization of the key with the other party? This is the key distribution problem for symmetric encryption.

A common solution today is to use asymmetric encryption and use the Diffie-Hellman key exchange algorithm. The core of asymmetric encryption is to generate a pair of keys, one is the public key and the other is the private key. The public key is used for encryption. It is public and can be distributed to anyone. The private key is used for decryption and does not participate in the communication process. , which needs to be properly kept, thus solving the key distribution problem. The core idea of ​​the Diffie-Hellman key exchange algorithm is that both parties can calculate the same shared key by exchanging some public information, but the eavesdropper cannot calculate the same key after obtaining the public information. One advantage of the Diffie-Hellman algorithm is that there is no performance problem of asymmetric encryption. Although asymmetric encryption solves the problem of key distribution, the operation speed of asymmetric encryption algorithms is far less than that of symmetric encryption algorithms, and they can even be hundreds of times faster. gap. Although security is ensured, it seriously affects the efficiency of communication and loses practicability. Therefore, in practical applications, symmetric encryption and asymmetric encryption are usually used in combination, that is, after using a pseudo-random number generator to generate a session key, encrypt it with the public key and send it to the other party. The session key, which will be used exclusively for subsequent communications. This not only solves the key distribution problem, but also solves the performance problem caused by asymmetric encryption, which is often called hybrid encryption.

integrity

仅仅具备机密性还不足以实现安全的通信,攻击者依旧可以篡改、伪造密文内容,而接收者既无法判断密文是否来自正确的发送者,也无法判断解密后的明文是否是未经篡改的。尽管对加密之后的密文进行针对性篡改的难度有所上升,例如篡改之后明文的数据结构很有可能会遭到破坏,这种情况下接收者能够很轻易地拒绝这个明文。但依然存在篡改之后正好使得解密得到的明文消息中某些本身就具备随机属性的字段的值发生变化的概率,例如电机转速字段的值从 500 变为了 718,无非是几个比特位的变化,如果接收者正常接受这些消息,就可能带来意想不到的隐患。

因此,我们还需要在机密性的基础上进一步保证信息的完整性。常见的做法就是使用单向散列函数计算消息的散列值,然后将消息和散列值一起发送给接收者。单向散列函数能够确保消息中哪怕只有 1 比特的改变,也有很高的概率产生不同的散列值。这样接收者就可以计算消息的散列值,然后对比收到的散列值来判断数据是否被人篡改。

身份认证

但可惜的是,当攻击者同时伪造消息和对应的散列值时,接收者依然无法识破这个伪装。因此我们不仅需要确认消息的完整性,还需要确认消息是否来自合法的发送者,也就是说还需要对身份进行认证。这个时候我们就需要用到消息认证码,消息认证码依然基于单向散列函数,但它的输入除了原本的消息以外,还包括了一个发送者与接收者之间共享的密钥。由于消息认证码本身并不提供消息机密性的保证,所以在实际使用中,通常会将对称加密与消息认证码结合使用,以同时满足机密性、完整性和认证的要求,这种机制也被称作认证加密(AEAD)。具体怎么使用上,产生了以下几种方案:

  1. Encrypt and MAC:先用对称密码将明文加密,再计算明文的 MAC 值,最后把二者拼接起来发给接收方。
  2. MAC then Encrypt:先计算明文的 MAC 值,然后将明文和 MAC 值同时用对称密码加密,加密后的密文发送给接收方。
  3. Encrypt then MAC:先用对称密码将明文加密,再后计算密文的 MAC 值,最后把二者拼接起来发给接收方。

在很长一段时间内,SSL/TLS 都采用了第二种方案,但事实上以上三种方案都已经陆续被验证为存在安全漏洞。SSL/TLS 历史上的 POODLE 和 Lucky 13 攻击都是针对 MAC then Encrypt 方案中的漏洞实现的。目前业界推荐的安全方案是采用 AEAD 算法,SSL/TLS 1.3 版本中也正式废除了其他加密方式,仅支持 AEAD 加密。

不可否认

现在,我们已经保证了消息的机密性,同时也能识别出伪装和篡改,但是由于消息认证码的核心是需要通信双方共享密钥,因此又引发了新的问题,即无法对第三方证明以及无法防止否认。假设 Bob 接收了来自 Alice 的消息,想要向第三方证明这条消息的确是 Alice 发送的,就需要将原本只有两个人知道的密钥告诉给第三方,这显然会增加后续继续使用这个密钥通信的安全风险。同时,即便第三方拿到了密钥,也无法得出有效的结论,例如 Bob 可以宣称这条消息是由 Alice 构造的,因为 Alice 也持有相同的密钥。

因此,我们还需要引入数字签名机制,它的原理与非对称机密很像,又正好相反。数字签名需要发送者用私钥对消息施加签名,然后将消息与签名一并发送给接收者,接收者则使用对应的公钥验证签名,确认签名来自合法的发送者。由于只有持有私钥的人才能施加正确的签名,这样发送者就无从否认了。而公钥只是用来验证签名,所以可以随意派发给任何人。可能敏感的读者到这里心中已经有些疑问了,是的,取到公钥的人如何确认这个公钥的确来自自己期望的通信对象呢?如果攻击者伪装成发送者,并把自己的公钥给了接收者,那么就能在无需破解数字签名算法的前提下完成攻击。

我们已经陷入了一个死循环,数字签名是用来用识别消息篡改、伪装以及否认的,但在此之前我们又必须从没有被伪装的发送者得到没有被篡改的公钥才行。到了这一步,我们只能借助外力的帮助了,委托公认的可信第三方,也就是我们现在常说的认证机构或 CA,由它来给各个公钥施加签名,形成公钥证书。显而易见的是,认证机构需要努力确保自己的私钥不被窃取,以保证数字签名的有效性。虽然认证机构的私钥依然有泄漏的概率,甚至认证机构本身也可能被攻击者伪装,我们依然无法获得绝对的安全,但提前信任几个已知的认证机构,总是比从全新的通信对象获取并信任他的公钥要可靠的多。

以上这些密码技术,共同构成了现代安全通信领域的基石。而 SSL/TLS 作为目前世界上应用最广泛的密码通信方法,综合运用了前面提到的对称加密、非对称加密、消息认证码、数字签名、伪随机数生成器等密码技术,来提供通信安全保障。考虑到密码学技术是不断进步发展的,或者说目前看似可靠的加密算法,可能在第二天就会被宣告攻破,所以 SSL/TLS 并没有强制使用某一种密码技术,而是提供了密码套件(Cipher Suite)这一机制,当某项密码技术被发现存在弱点,可以随时像零件一样替换它,当然前提是客户端和服务端使用相同的密码技术。这也延伸出了 SSL/TLS 的握手协议,协商使用的密码套件就是这一部分协议的主要工作之一。

想要 SSL/TLS 具备良好的安全性,就需要避免使用已经被攻破或者已经被验证为弱安全性的加密算法,要避免使用容易被预测的伪随机数生成器,要尽量保证各个算法具有近似的安全性(短板效应)。

因此,如何正确选择密码套件,也成为了保障安全性的一个重要环节。这里我也会对目前推荐的密码技术和加密算法进行一个简单的整理,希望可以帮助各位读者查漏补缺:

  • 对称加密算法中 RC4、DES、3DES 都已经被认为是不安全的了,目前推荐使用的只有 AES 和 ChaCha20。ChaCha20 是 Google 设计的一种加密算法,如果 CPU 或软件不支持 AES 指令集,ChaCha20 可提供比 AES 更好的性能。
  • AES 这类对称加密算法只能加密固定长度的明文,想要加密任意长度的明文,还需要用到分组模式。早期的 ECB、CBC、CFB、OFB 等分组模式已经被认定为存在安全漏洞,目前更推荐使用 GCM、CCM 和 Poly1305。
  • 常用的非对称加密算法有 DH、RSA、ECC 这几种。由于 DH 和 RSA 都不具备前向安全性,目前已经不推荐使用,TLS 1.3 中更是直接废除了 DH 和 RSA 算法,取而代之的是安全强度和性能都明显优于 RSA 的 ECC 算法,它有两个子算法,ECDHE 用于密钥交换,ECDSA 用于数字签名。但需要注意的是,由于 ECDHE/DHE 不提供身份验证,因此服务端应当启用对客户端证书的验证。
  • 散列算法方面,我们熟知的 MD5 和 SHA-1 都已经被认定为不再可靠,不推荐继续使用。目前通常建议使用 SHA256 或更高版本。

在了解推荐使用的密码技术以后,也许我们想要修改客户端或服务端的密码套件配置,但此时我们可能会发现这些密码套件的名称还有点难以理解。例如 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,其中 TLS 只是表示协议,ECDHE 表示密钥交换算法,ECDSA 表示身份认证算法,AES_256_CBC 表示批量加密算法,SHA384 表示消息认证码 MAC 算法。这通常是 TLS 1.2 中密码套件的命名格式,而到了 TLS 1.3 则又发生了一些变化。由于 TLS 1.3 只接受使用 ECDHE 算法进行密钥交换,并且使用 ECDSA 进行身份认证,因此它的密码套件名称可以精简成 TLS_AES_256_GCM_SHA384 这种格式。

如果仅从安全性角度出发,个人建议使用 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 和 TLS_AES_256_GCM_SHA384。但考虑到目前仍有很多以 RSA 方式签发的证书正在使用,因此我们还需要根据自身情况来选择是否要继续使用 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384。

构建安全认证体系典型架构

采用基于 PKI/CA 的数字证书体系是解决车联网安全关键的一步,也是大多数车企典型安全管理体系。其主要的设计思路如下:

  1. 基于数字证书的身份标识:通过 PKI/CA 系统建立严谨的证书管理和使用规范,为车联网的应用和终端颁发数字证书,虚拟身份和真实身份进行绑定,解决身份标识和唯一性问题(可实现一机一密或一型一密);
  2. 所有数据交互时通过终端的身份唯一标识证明身份的真实性,防止第三方恶意入侵;
  3. 基于数字证书安全功能,提供身份鉴别、身份认证、数据加解密、数字签名与验签等多种功能,满足车联网中 TSP、OTA 等多业务安全需求。

Internet of Vehicles Security.png

车联网平台安全通信交互流程,一般是将车机端申请终端证书,下载并完整安装后通过 MQTTS 安全协议与云端平台请求建立安全连接。在云端我们可以选择在云厂商的负载均衡产品、基于 Nginx/HAProxy 自行搭建的 LB 层或是 MQTT Broker 层进行认证鉴权,同时通过 proxy_protocol v2 将车机端的 ID 信息、用户名密码及证书的 CN/SN 等信息通过调用 PKI/CA 统一认证接口进行唯一性认证,实现一机一密或一型一密的安全认证。

MQTTS 通信中单、双向认证的配置方式

SSL/TLS 连接认证认证的是对方身份,是否是可信的通信对象,认证的依据则是通信对象提供的证书。通常情况下是由客户端对服务端的身份进行认证,也就是所谓的单向认证。那么双向认证顾名思义就是在单向认证的基础上,服务端对客户端的身份进行认证。

认证的原理其实非常简单,以单向认证为例,最简单的情况就是服务端在 SSL/TLS 握手阶段发送服务端证书,客户端验证该证书是否由受信任的 CA 机构签发,也就是使用受信任的 CA 证书中的公钥来验证服务端证书中的数字签名是否合法。当然大部分情况会比这个稍微复杂一些,即服务端的证书不是由最顶层的 CA 机构直接签发的,而是由根 CA 机构对下层 CA 机构的公钥施加数字签名,形成中间 CA 证书,这样的关系可能会多达几层,以尽可能保护根证书的安全。大部分情况下常见 CA 机构的根 CA 证书和中间 CA 证书都已经内置在我们的操作系统中了,只有少数情况下需要自行添加信任的 CA 证书。

多级证书或者说证书链的认证过程会稍微复杂一些,但如果我们搞明白了前面说的证书签发逻辑,其实理解起来也很简单。还是以单向认证为例,如果客户端只信任了根 CA 证书,那么服务端在握手阶段就需要发送服务端证书和根 CA 证书到服务端证书之间的所有中间 CA 证书。只有客户端拿到了完整的证书链,才能通过自己持有的根 CA 证书一层一层往下验证,缺少中间 CA 导致证书链不完整或者包含了错误的中间 CA,都会导致信任链中断而无法通过认证。

如果客户端除根 CA 证书以外,还持有一部分中间 CA 证书,那么在认证过程中,服务端还可以省略这些中间 CA 证书的发送,来提高握手效率。

因此,当我们配置单向认证时,需要在服务端指定服务端证书和中间 CA 证书(可选),以及服务端私钥文件。客户端则需要信任相应的根 CA 证书,信任的方式可以是在连接时指定或者通过证书管理工具将该根 CA 证书添加到信任列表。通常客户端库还提供了对端验证选项允许选择是否验证证书,关闭对端验证将在不验证证书的情况下直接创建加密的 TLS 连接。但这会带来中间人攻击的安全风险,因此强烈建议启用对端验证。

在启用对端验证后,客户端通常还会检查服务器证书中的域名(SAN 字段或 CN 字段)与自己连接的服务器域名是否匹配。如果域名不匹配,则客户端将拒绝对服务器进行身份验证或建立连接。

双向认证的配置方式只需要在单向认证的基础上,在服务端启用对端验证即表示启用双向认证以外,再参考服务端证书的配置方式正确配置客户端证书即可。

常见 TLS 选项介绍

当使用 EMQX 配置 SSL/TLS 连接时,通常会有 certfile、keyfile 等选项,为了帮助大家更好地了解这些选项的配置方式,接下来我们会对这些常见的 TLS 选项做一个简单的梳理和介绍:

  • certfile,用于指定服务端或客户端证书和中间 CA 证书,需要指定多个证书时通常将它们简单地合并到一个证书文件中即可。
  • keyfile,用于指定服务端或客户端私钥文件。
  • cacertfile,用于指定 Root CA 证书,单向认证时客户端需要配置此选项以校验服务端证书,双向认证时服务端也需要配置此选项以校验客户端证书。
  • verify,用于指定是否启用对端验证。客户端启用对端验证后通常还会去检查连接的服务器域名与服务器证书中的域名是否匹配。客户端与服务端同时启用则意味着这将是一个双向认证。
  • fail_if_no_peer_cert,这是一个服务端的选项,通常在服务端启用对端验证时使用,设置为 false 表示允许客户端不发送证书或发送空的证书,相当于同时开启单向认证和双向认证,这会增加中间人攻击的风险。
  • versions,指定支持的 TLS 版本。通信双方会在握手过程中,将 versions 选项中指定的版本发送给对方,然后切换至双方都支持的最高版本。同时也会基于该协议版本来协商密码套件。
  • ciphers,指定支持的密码套件。注意事项:避免使用前文提到的或其他被认定为弱安全性的密码套件,以及当使用包含 ECDSA 签名算法的密码套件时,需要额外注意自己的证书是否为 ECC 类型。
  • server_name_indication, the server name indication, this is a client-side option. Usually used when the client has peer-to-peer authentication enabled and the connected server domain name does not match the domain name in the server certificate. For example, the domain name in the server certificate is abc.com, and the client connects to 123.com, then the client needs to specify server_name_indication as abc.com when connecting to indicate that it trusts the domain name to pass the certificate check. Alternatively, set server_name_indication to disable to turn off this check, but this increases the risk of man-in-the-middle attacks and is generally not recommended.

Example

For the convenience of demonstration, we will use EMQX (version 4.3.0 and above) as the server, and use Erlang's ssl:connect/3 function as the client in the EMQX console.

One-way authentication

Modify the EMQ X configuration as follows:

# 监听端口我们使用默认的 8883
listener.ssl.external = 8883
# 服务端私钥文件
listener.ssl.external.keyfile = etc/certs/zhouzb.club/Nginx/2_zhouzb.club.key
# 证书捆绑包文件,包含了服务端证书和中间 CA 证书
listener.ssl.external.certfile = etc/certs/zhouzb.club/Nginx/1_zhouzb.club_bundle.crt
# 不开启对端验证
listener.ssl.external.verify = verify_none
# 支持 TLS 1.2 和 TLS 1.3
listener.ssl.tls_versions = tlsv1.3,tlsv1.2
# 服务端支持的密码套件
listener.ssl.external.ciphers = TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_128_CCM_SHA256,TLS_AES_128_CCM_8_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
复制代码

Start EMQ X and enter the console:

$ ./emqx console
复制代码

To connect using the ssl:connect/3 function:

%% 1. 指定用于验证服务端证书的 Root CA 证书
%% 2. 启用对端验证
%% 3. 仅支持 TLS 1.2
%% 4. 仅支持 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 这一个密码套件
ssl:connect("zhouzb.club", 8883, [{cacertfile, "etc/certs/zhouzb.club/DigiCertGlobalRootCA.crt.pem"},
                                  {verify, verify_peer},
                                  {versions, ['tlsv1.2']},
                                  {ciphers, ["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"]}]).
复制代码

Two-way authentication

In order to get to the point as soon as possible, the server certificate will continue to be used as the client certificate, which will have serious security risks. Please prohibit such use in the production environment!

Modify the EMQ X configuration as follows:

# 监听端口我们使用默认的 8883
listener.ssl.external = 8883
# 服务端私钥文件
listener.ssl.external.keyfile = etc/certs/zhouzb.club/Nginx/2_zhouzb.club.key
# 证书捆绑包文件,包含了服务端证书和中间 CA 证书
listener.ssl.external.certfile = etc/certs/zhouzb.club/Nginx/1_zhouzb.club_bundle.crt
# 指定用于验证客户端证书的 Root CA 证书
listener.ssl.external.cacertfile = etc/certs/zhouzb.club/DigiCertGlobalRootCA.crt.pem
# 启用对端验证
listener.ssl.external.verify = verify_peer
# 要求客户端必须提供证书
listener.ssl.external.fail_if_no_peer_cert = true
# 支持 TLS 1.2 和 TLS 1.3
listener.ssl.tls_versions = tlsv1.3,tlsv1.2
# 服务端支持的密码套件
listener.ssl.external.ciphers = TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_128_CCM_SHA256,TLS_AES_128_CCM_8_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
复制代码

Start EMQ X and enter the console, then use the ssl:connect/3 function to connect:

%% 1. 指定用于验证服务端证书的 Root CA 证书
%% 2. 启用对端验证
%% 3. 仅支持 TLS 1.2
%% 4. 仅支持 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 这一个密码套件
ssl:connect("zhouzb.club", 8883, [{cacertfile, "etc/certs/zhouzb.club/DigiCertGlobalRootCA.crt.pem"},
                                  {certfile, "etc/certs/zhouzb.club/Nginx/1_zhouzb.club_bundle.crt"},
                                  {keyfile, "etc/certs/zhouzb.club/Nginx/2_zhouzb.club.key"},
                                  {verify, verify_peer},
                                  {versions, ['tlsv1.2']},
                                  {ciphers, ["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"]}]).
复制代码

Epilogue

The "Guidelines for the Construction of Internet of Vehicles Network Security and Data Security Standard System" issued by the Ministry of Industry and Information Technology clearly pointed out that it is necessary to build a standard system for Internet of Vehicles network security and data security. Network communication security and data security in the field of Internet of Vehicles will receive more and more attention, which is one of the key factors for improving the competitiveness of Internet of Vehicles enterprises. It is hoped that through this article, readers can master the use of the SSL/TLS protocol, apply it correctly in actual business scenarios, and realize the security of Internet of Vehicles communication.

Copyright statement: This article is original by EMQ, please indicate the source when reprinting.

Original link: www.emqx.com/zh/blog/ssl…

Guess you like

Origin juejin.im/post/7086674077393354760