简单描述下业务场景,我们期望使用X.509证书来实现对终端设备的授权。
首先在终端设备内置根证书,当终端收到服务端下发的授权证书后,使用内置根证书对授权证书进行验证,验证通过即代表授权证书是由服务端所颁发。
在根证书和授权证书中间也可能存在多个中间证书,有多个证书的情况下对证书进行合并后下发。
假设已有证书的签发顺序如下:
根证书root.pem -> server.pem -> device.pem
第一轮尝试验证
// 合并证书服务证书与终端授权证书
cat server.pem device.pem > app.pem
// 使用根证书对授权证书链进行验证
openssl verify -CAfile root.pem app.pem
// 输出
app.pem: OK
得到的结果是验证通过,看上去符合预期的结果。
但是,随着继续测试问题就出现了
// 合并一个完全不相干证书作为三级证书
cat server.pem other.pem > app.pem
// 再次使用根证书进行验证
openssl verify -CAfile root.pem app.pem
// 输出
app.pem: OK
得到的结果依然是通过验证。。。
最终经过几次测试得出结论,验证合并的多张证书时,其实还是只验了证书链中的第一个证书。
这很显然不符合我们的需求。
预期的流程图如下,但灰色部分并未执行
第二轮尝试验证
我又做了些尝试,这次使用合并后的证书作为CAfile,去验证device证书,如下:
// 合并服务器证书与根证书
cat server.pem root.pem > ca.pem
// 使用合并后的CA验证终端授权证书
openssl verify -CAfile ca.pem device.pem
// 输出
device.pem: OK
得到的结果是通过,符合预期。
紧接着我又又测试了
// 合并一个毫不相干的证书到CA证书链顶部
cat other.pem server.pem root.pem > ca.pem
// 测试验证终端授权证书
openssl verify -CAfile ca.pem device.pem
// 输出
device.pem: OK
得到的结果依然是通过,这。。。
再经过多次测试后,发现ca.pem中的证书集合在验证时,如果其中任何一个验证成功,则直接返回,不再对后续证书进行验证,因为这时已经可以确认device与root的关系。
流程如下图:
每次在CA证书链对授权证书进行验证时,都需要先对自身链上证书进行校验,通过后再对授权证书进行校验;
第1、3、5步,任何一步校验失败,则说明CA证书链有问题,直接返回失败;
第2、4、6步,任何一步校验成功,则说明在证书链找到了device的签发者,直接返回成功。
我们的目标是保证从根证书到授权证书这条线的安全,目前已经基本满足了需求。
在测试的过程中还发现一些其他问题,比如说如果未设置basic constraints属性,在Ubuntu系统下会报error 24 at 1 depth
,Ubuntu对证书的算法也要求严格,需要使用SHA256等等。
Comments | NOTHING