一.理解RSA的算法原理
1.加解密算法的通用理解框架
我对加解密算法的理解一般抓住两个主要的方面:一个是算法的对称性,即明文信息通过一次加密、解密操作之后依然还原为明文,这个对称性可以理解为信息关于“加密、解密”这组行为对称。另一个算法的安全性,即为什么我们无法根据公开信息和密文等推导出明文。
2.理解RSA
2.1.构造RSA的对称性
由于RSA为非对称加解密算法,因此计算过程需要一对密钥,假设公钥为e,私钥为d,明文信息为M,密文信息为C,我们可以得到:
C = Encrypt(M, e)
根据加解密算法的对称性,我们需要满足:
M = Decrypt(C, d) = Decrypt(Encrypt(M, e), d)
即我们对M进行关于e的某种运算后,接着进行关于d的某种运算,得到的结果依然为M。RSA选择了同余作为这里的运算方法,结合同余我们可以将如上等式转化为:
M ≡ C^d ≡ M^ed (mod N)
因此我们需要构造满足如下等式成立的条件:
M ≡ M^ed (mod N)
所以接下来的任务是如何选择e、d和N的值。RSA在这里使用了欧几里得算法,即对于两个互质的数a、b,一定存在x、y使得ax + by = 1,这个公式的含义其实就是a和b的最大公约数为1,公式变形为ax = by + 1也是同样的意思。
我们接着思考,如果以a为加密密钥,以x为解密密钥,那么要使得M ≡ M^ed (mod N) 成立,则必须满足如下条件:
M^by ≡ 1 (mod N)
这个时候,科学家们想到了费马定理:
m^φ(N) ≡ 1 (mod N)
φ(N)即欧拉函数,他的计算公式为φ(N) = (p-1)(q-1),其中N = pq,p和q为一对质数。
很自然地我们可以令b=φ(N),则M^b ≡ 1 (mod N)成立,M^by ≡ 1 (mod N)也同样成立。
综上,当N=pq,p和q为一对质数,就可以构造出满足对称性的加解密密钥,加解密密钥满足:
ed = φ(N) + 1
其中e、N是公开的,d、p、q是保密的。
2.2.RSA的安全性
根据2.1的推论,e是公开的,如果想通过e推导出d,需要知道φ(N)的值,而φ(N) = (p-1)(q-1),因此需要知道p和q的值。
这里就到了RSA安全性的精髓,即如果我们选择两个特别大的质数p和q,计算得到N的过程是很容易的,但是根据N反推p和q的值是相当困难的,这就是我们常说的大数分解难题,也是RSA安全性的根本。
二.RSA在工程实践中的应用要点
1.第一用途是什么
在工程实践中,我们首先需要区分算法的第一用途,即加解密还是签名、认证等等,RSA在加解密、签名验签和身份认证等领域均有用武之地,至于是否应该选择RSA,还需要考虑接下来的多个方面。
2.密钥基础设施
2.1.是否需要公开的密钥
如果需要将公钥公开给多个终端,则可以考虑使用RSA。在车内通信的场景下,很多时候密钥都要求存储在se芯片或者hse模块中,因此可以认为无论对称密钥或非对称密钥,密钥的保密性都是能够得到保证的,如果不考虑性能等因素,对称加密和非对称加密在一定程度上可以达到相同的效果。但如果存在必须公开公钥的需求,那么首先应该考虑使用RSA。
2.2.密钥的生成
车联网中使用到的密钥一般在云端密钥系统统一生成,然后分发给各个终端。在一些涉及到供应商提供ECU固件的场景下,可能会需要供应商生成用来签名验签固件的密钥。
2.3.密钥的分发
通过云端密钥系统生成的密钥,可以通过云端的分发接口直接分发给各平台。例如云端密钥服务器提供下发密钥的api,各个终端通过api请求获取云端密钥。为保证安全性,云端密钥系统需要对终端请求进行身份认证和权限控制,防止非法获取密钥。并且密钥在传输过程中最好经过加密之后再进行传输,以保证传输的安全性。
通过se芯片或hse模块生成的密钥,主要分发场景是在车内各个域之间进行分发,这个时候需要考虑域间通信机制的安全性,最好也能够先加密再传输。
对于供应商生成的密钥,其私钥最好由供应商自己保存,这样可以保持清晰的责任边界,防止密钥泄露之后责任定义不清的问题。主机厂需要对供应商提出明确的要求和约束,以保证私钥的安全性。
2.4.密钥的存储
云端密钥的存储需要综合考虑容灾备份、可用性和安全性等方面,特别是根密钥的存储,一般会采用线下物理安全的手段来保证根密钥的安全性。
对于车内各个域的密钥存储,最好存储在se芯片或hse模块之中,通过芯片的安全特性保证密钥的安全性。在芯片存储空间紧张的情况下,可以考虑使用se或hse加密密钥之后存储到flash之中。
对于手机等移动终端上与车或云交互的应用程序,推荐将密钥进行混淆或使用白盒的方式进行存储,再配合应用加固等app保护技术,来加强密钥的安全性。
2.5.密钥的生命周期
用于签名验签的密钥和证书,需要考虑证书的有效期,以防止出现有效期太短影响车内验签功能的正常运行。
对于安全性要求极高的场景,建议使用一次一密或一车一密,防止一辆车发生密钥泄露之后风险扩散到所有车辆。
3.平台特性
能够使用RSA的前提是平台能够很好地支持rsa算法,这一点在一些受限的嵌入式设备上尤其重要。
4.性能
RSA由于加解密过程中的模幂运算比较耗时,所以从性能上远不及AES。在需要考虑性能的场景下,比如一些车内ecu对启动时间要求较高,必须在上电后100ms或200ms内开始响应,这个时候就需要严格评估使用RSA作为ecu安全启动的验签算法的耗时,如不能满足要求,则应该果断放弃,改为采用AES、CMAC等效率较高的算法。
5.密钥长度
对于存储空间敏感的设备,需要考虑密钥存储空间是否够用。RSA最低要求1024bit的存储空间,如果无法满足,也应该考虑选择其他密钥长度较短的算法。
6.填充方式
6.1.RSA_NO_PADDING
使用RSA加密时,如果明文不够128字节,加密的时候会在明文前面填充若干数据0,直至达到128字节。 解密后的明文也会包括前面填充的零,需要把解密后的字段前向填充的零去掉,得到真正的明文。
6.2.RSA_PKCS1_PADDING
如果明文不够128字节,加密的时候会在明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样。 对加密后的密文,用户使用相同的填充方式都能解密。解密后的明文也就是之前加密的明文。因为引入了随机填充,所以安全性高于RSA_NO_PADDING。
6.3.RSA_PKCS1_OAEP_PADDING
RSA_PKCS1_OAEP_PADDING填充模式是PKCS#1推出的新填充方式,安全性最高,和前面RSA_PKCS1_PADDING的区别就是加密前的编码方式不一样,推荐直接使用OAEP的方式进行填充。
7.安全性
从理论上来讲,ECC的安全性优于RSA。但是在实际的工程实践中,我们认为这种安全性差异基本可以忽略。另外,在工程实践中,我们也没有非常标准和可量化的方式来评估安全需求所要达到的安全等级是否因采用RSA或ECC。
三.RSA在车联网安全中的常见应用场景
1.二进制文件验签
1.1.安全启动
车辆的主要信息娱乐域、整车域、自动驾驶域及一些重要传感器ECU等均需要安全启动保证底层固件、操作系统和上层app的合法性及完整性。在启动时间要求不是特别严格的情况下,常使用RSAwithSHA256作为安全启动的签名验签算法。
1.2.OTA
OTA在智能网联车中的应用已经非常普遍,系统OTA升级过程中需要对固件包的合法性进行验证,典型的场景如刷写固件前对固件包的签名进行验签,经过完整性和合法性验证的固件包才会执行刷写,这个过程中经常使用RSA作为验签算法。
1.3.可执行脚本
在涉及到车辆动态执行云端下发的脚本时,也需要考虑脚本文件的合法性和完整性,推荐执行脚本之前以RSA作为验签算法对脚本文件进行验签。
1.4.配置文件
与动态脚本类似,云端下发的一些重要的配置文件也需要考虑合法性和完整性,推荐加载配置文件之前以RSA作为验签算法对脚本文件进行验签
2.密钥加密
密钥在传输、灌装、存储等环节,有时会需要加密之后再进行,一般使用RSA对原始密钥进行加密,对密钥进行加密传输、灌装和存储,在使用时解密后使用。
3.密钥协商
在需要协商会话密钥的场景下,RSA可以用来加密随机数,完成随机数的交换,让通信双方安全地生成会话密钥。
4.身份认证
在车云通信及车与移动端通信等场景下,车端需要对云端和手机端的身份进行认证,可以使用RSA公钥加密随机数发送给对方,根据对方解密后返回的数值判断对方是否持有指定私钥,以验证对方的身份。