最近因为工作,手写了一个双向认证库,可以在Java和Android中使用,不限于PC/手机和车载平台。首先我们看一下双向认证的一些基本框架设计思路。最后,我们将提供下载链接或源代码供您参考。
它在这里也被称为Flex 双向身份验证,因为它可以与FlexNet 网络库一起使用(请参阅我创建的网络库:文章链接)。
原理
Flex 双向身份验证是基于标准HTTPS 的安全身份验证。在讨论双向身份验证之前,我们需要了解标准的HTTPS。 HTTP是HTTPS通信的基础,所以要了解HTTPS就必须先了解HTTP。
HTTP(HyperText Transport Protocol)超文本传输协议。用于发送客户端和服务器端数据。
HTTP标准交互流程
尽管HTTP 非常简单且易于使用,但它存在三个关键问题:
通过明文通信,内容可能会被拦截。如果您无法验证与您通信的人的身份,则存在伪造的风险。消息的完整性无法被证明并且很容易被篡改。
HTTPS通信
HTTPS是在HTTP协议的基础上添加加密机制来解决上述问题的通信解决方案。根据您的需求,主要分为单向认证和双向认证。
单向认证
在单向身份验证过程中,客户端验证服务器颁发的服务器端公钥证书并建立安全通信通道。
双向认证
在双向通信过程中,客户端除了验证服务器颁发的服务器公钥证书外,还必须将客户端的公钥证书上传到服务器以供服务器验证。一旦双方通过身份验证,就建立了安全的通信通道来进行数据传输。
Flex双向认证
Flex库选择了更安全的双向身份验证方案。它还处理证书安全。
资源配置
APP需要从汽车和电脑获取相应的证书,才能进行下一步的双向认证。
统一的SSLLib
为了避免每个APP都需要开发单独的双向认证方案,实现了Flex双向认证工具库。
获取车机资源进行认证
构建双向身份验证所需的对象HttpsUtils.buildSSL。该方法为异步回调,必须等待回调执行后续的双向认证逻辑。
/**
* 构建SSL证书
*在应用程序内调用时,设置在主进程内使用时必须注意,防止多进程引发异常。
*
* @param ctx 上下文必须用于检索汽车和机器的内置资源。
* @paramcallback 回调双向认证所需的资源。 null 表示构建失败
* */
私人乐趣buildCarSSL() {
HttpsUtils.buildSSL(this) {
mCarParams=它
Log.e(\’SSL\’, \’buildCarSSL:${it==null}\’)
}
}
使用OKHTTP 配置双向身份验证
/**
* 创建默认的OkHttpClient
* 和服务器协议信息
* */
私人乐趣buildOkHttpClient(): OkHttpClient {
val clientBuilder=OkHttpClient.Builder()
//构造双向认证对象SSLParams
if (MainActivity.mCarParams !=null) {
val ssl=主要活动!
clientBuilder.sslSocketFactory(ssl.sslSocketFactory,ssl.trustManager)
}
//不验证主机。如果需要验证主机,可以将主机名与需要调用的服务器进行比较。
clientBuilder.hostnameVerifier { 主机名,会话- true }
mInterceptors.forEach {
clientBuilder.addInterceptor(it)
}
if (BuildConfig.DEBUG) {//输出调试日志
val httpLoggingInterceptor=HttpLoggingInterceptor()
httpLoggingInterceptor.level=HttpLoggingInterceptor.Level.BODY
clientBuilder.addInterceptor(httpLoggingInterceptor)
}
clientBuilder.connectTimeout(OkHttpConst.CONNECT_TIME, TimeUnit.SECONDS)
clientBuilder.readTimeout(OkHttpConst.READ_TIME, TimeUnit.SECONDS)
返回clientBuilder.build()
}
自定义资源进行认证
构造双向身份验证所需的对象SSLUtils.getDoubleSslFactory。
/**
* 用于调试TODO:演示的证书配置。对应的服务器是demo测试云。如果您需要自己测试,您应该使用自己的云配置和修改。
* 参见@LocalSSLApiStore.baseUrl
* */
私人乐趣buildLocalSSL() {
val caIs=assets.open(\’ca-cert.pem\’)
val clientPfxIs=assets.open(\’client.p12\’)
val clientPsd=\’hbzq253503125\’
//mSSLParams=SSLUtils.getSingleSslFactory(
//arrayOf(caIs)
//)
//双向认证
mSSLParams=SSLUtils.getDoubleSslFactory(
arrayOf(caIs),
clientPfxIs、clientPsd
)
}
QA
如果您需要查看Lib库日志以进行故障排除或总结问题原因,请设置SSLLogUtils#init。
CODE码对照表
CODE 代码(详细信息请参阅SSLConst 类) 值/整数的含义CODE_SUC0 成功构造CODE_DUPLICATION1~~重复检索~~自v1.3.0 起此错误代码不再存在CODE_OVERTIME2 检索超时CODE_PKI_ERROR3 PKI 获取资源时发生错误。通常问题出在ROM CODE_CERTS_ERROR4 上。通常该证书不存在。用户在检索证书时可能已将其解锁,或者PKIAutoInstall 可能未检测到包名称。应用程序检测到证书的存在并请求ROM 中的白名单或系统权限。一般来说,ROM的PKIAutoInstall没有检测到应用程序的包名。要推送应用程序并重新启动设备,您必须使用push~~。通过使用~~.install 安装应用程序并重新启动汽车以触发ROM 权限和包名称验证,我可以获得成功的CODE_THREAD_ERROR5HttpsUtils。从v1.5.0开始,这个错误不是.buildSSL调用的线程。 CODE_CONTEXT_ERROR6 当应用程序检索上下文失败时回调此错误代码。
如果您看到上面的错误代码,请参阅故障排除。
问题排查
HttpsUtils.buildSSL 返回null 并解决问题以查看您的工作台或车辆是否包含证书。
aar版本(=v1.1.0)仅支持系统应用程序,无论是否是系统应用程序。如果是通过系统应用获取的,需要向@QinJinchuan确认该应用是否为系统应用。系统应用的权限申请也是和他协商的。
车机或台架证书是否刷写成功。
要获取证书,必须先解锁用户,然后通过白名单方案获取证书。请务必确保您的应用程序已应用于白名单(如果需要添加新列表,可以查看@贴子)。 (也适用于他),已验证的rom=W48D6
无论您的应用程序是否在当前ROM的白名单中,第一次刷入证书后,您可以收集日志并检查PKIAutoInstall关键字TAG,看看它是否有自己的包名。
使用oktb 时列入白名单的应用程序列表
?xml 版本=\’1.0\’ 编码=\’utf-8\’?
资源
数组名称=\’grantPackage\’
itemcom.here.hnod.elise.elise_navigation/item
itemcom.abupdate.ota/item
itemcom.example.manual/item
/大批
/资源
您只需要自己配置JAR 访问权限,无论权限是否添加到应用程序的清单文件中。
使用权限android:name=\’com.ecarx.security.READ_CA_CERTIFICATE\’/
如果您按照上述步骤后仍无法成功找回证书,请检查问题所在。
常见问题
当您引入AAR 或Maven 依赖项时,您会收到一条消息,指出该模块是使用不兼容的Kotlin 版本编译的。
这是因为该库开发的kotlin版本是1.7.10,所以如果版本低于1.7,由于项目中引入了ID“org.jetbrains.kotlin.android”的版本“1.6.20”lint。检测失败。10,所以你需要升级你的kotlin版本。
如果不想升级,可以配置lint忽略检测(不推荐这种方法)。
棉绒选项{
checkReleaseBuilds false
错误中止错误
}
调用HttpsUtils.buildSSL 时出现权限相关问题
检查调试的应用程序是否经过系统签名。签名验证通常会失败,无法获得许可。
该请求显示消息“链验证失败或验证服务器的证书不正确”。
首先检查服务器是否配置了相应的双向认证证书,然后检查日志中的台车时间或实车时间是否正确。
如果服务器配置正确,则该问题是由机器或工作台计时异常引起的。
请求返回客户端证书异常
请检查您的台架或实车对应的证书是否刷入,ROM****版本必须为2022/9/15。
双向身份验证失败,检索证书返回的错误为空。
证书刷新通常会失败。如果确认证书刷新成功,请检查以下三项:
主从版本必须一致
证书必须在master 上闪烁
rom 和证书必须是CN 或EU
部署双向认证aar后,使用车机调试报javax.netssl.SSLPeerUnverifiedException: hostname xxx not verify错误
必须设置clientBuilder.hostnameVerifier 验证
测试的RESTful API 返回错误
服务器返回的内部错误表明双向身份验证已完成。这是服务器接口内部逻辑的问题。请联系相应的服务器开发商。
即使SDK成功检索到证书,请求仍然报握手错误。
请参阅分析TLS 协议和使用Wireshark 抓包来检查您的云和车辆证书环境是否一致。
接入相关
集成后,您只需两步即可实现该功能:
获取证书
/**
* 为Lotus构建SSL证书
*在应用程序内调用时,设置在主进程内使用时必须注意,防止多进程引发异常。
*
* @param ctx 上下文必须用于检索汽车和机器的内置资源。
* @param isByWhiteList 是否以白名单模式获取证书
* @param overtime 配置超时时间。 SSLMills.MILLS_MIN 表示回调成功或失败之前不会超时。
* 其他时间仅限于SSMills,并表明此计划必须在指定时间完成操作。否则会在指定时间回调,并返回null和指定的错误码。
* @param监听器回调监听结果[SSLConst.CODE_SUC]和[SSLParams]
* */
玩得开心构建SSL(
ctx: 上下文,
isByWhiteList: 布尔值=false,
@SSLMills 加班: 长=SSLMills.MILLS_MIN,
监听器: SSL监听器
)
对应网络库设置双向认证的配置
目前存在多种网络协议,下面列出了一些常用的协议。
OKHttp
MQTT
WebSocket
要解决问题,您必须启用日志记录并配置SSLLogUtils#init。
/**
* 只需在应用程序中设置即可。必须在检索双向身份验证设置之前调用。
* @param ctx 获取集成应用程序的包名
* @param Enable 是否向控制台输出日文
* @param logAdapter 提供给开发者使用自定义日志工具。默认情况下直接使用[DefaultLogAdapter]。
* */
有趣的初始化(
ctx: 上下文,
Enable: 布尔值=BuildConfig.DEBUG,
logAdapter: ILogAdapter?=DefaultLogAdapter()
)
简易Demo
使用该库的简单演示
该内容目前无法显示在文档之外
该演示提供SSLSocketUtils 来演示重试检索双向身份验证配置的逻辑,提供HostnameVerifierUtils 来监视双向身份验证配置、检索结果并发出下一个网络请求。该演示展示了如何使用SSLLogUtils 调试日志。
混淆配置
开发者集成后,可以以AAR的形式提供给第三方。
-保留类com.max.ssl.SSLUtils {*;}
-保留类com.max.ssl.SSLMills {*;}
-保留类com.max.ssl.SSLConst {*;}
版本日志
各个发布版本的更新日志,时间闪回。
版本发布规则
4 位版本号(v1.0.0.0)、错误修复和更新更改了最后一个(左起)版本号。次要版本(不影响访问)在添加方法或参数时更改第三位数字。 只有当计划发生重大变化时才会发生第一次版本号更改。
3 位版本号(v1.0.0.0)、错误修复或次要版本(不影响访问) 添加方法或参数时更新和更改最后一个(左起)版本号。仅当计划发生重大变更时才会进行版本号更改。
V1.6.1
集成白名单和系统应用逻辑来检索证书和更新演示配置信息
Jar
添加了直接提供jar 包的功能。这就需要开发者在manifest中配置相应的权限和配置。
使用权限android:name=\’android.permission.INTERNET\’ /
使用权限android:name=\’com.ecarx.security.READ_CA_CERTIFICATE\’/
Lib中使用的依赖必须由开发者自己导入
实现“androidx.annotation:annotation:1.5.0”
该内容目前无法显示在文档之外
AAR
该内容目前无法显示在文档之外
V1.6.0
该内容目前无法显示在文档之外
新的buildSSLAtMaster支持在主Soc上获取双向身份验证证书(当前解决方案仅支持系统应用程序和CN/EU车机)并支持自定义日志记录类。默认情况下,lib 使用Android 的默认日志记录工具类来实现。打印日志。
/**
*
* 开发人员可以实现此接口并将此对象设置为[com.max.ssl.SSLLogUtils] 以使用自定义日志记录实现。
*/
接口ILogAdapter {
趣味日志(@LogLevel logLevel: Int,tag: String,content: String)
}
该演示添加了一个新的buildMasterSSL 方法来测试通过主Soc 的证书检索。
V1.5.0.1
该内容目前无法显示在文档之外
提高了对低版本ROM的兼容性,让romW14D4也能成功检索证书,去除异常匹配证书的隐藏解决方案,并直接返回检索失败。
V1.5.0.0
注意:rom=W14D4(RC04以外的版本;必须使用主线版本,例如20.32.20.000001.231661)
该内容目前无法显示在文档之外
增加获取证书时的处理,防止过程中获取证书失败。 将日志库固定为集成工具库。如果要直接引入,则需要引入木头。
implementation \’com.jakewharton.timber:timber:5.0.1\’//可以自己指定版本
V1.4.0.2
该内容目前无法显示在文档之外
添加获取证书时的异常处理
V1.4.0.1
该内容目前无法显示在文档之外
更改混淆配置以防止与其他库冲突。
V1.4.0.0
该内容目前无法显示在文档之外
SSLLogUtils增加了一个init方法来检索集成应用程序包名称,以方便后续调试。
/**
* 只需在应用程序中设置即可。必须在检索双向身份验证设置之前调用。
* @param ctx 获取集成应用程序的包名
* @param Enable 是否向控制台输出日文
* */
有趣的初始化(ctx:上下文,enable:布尔=BuildConfig.DEBUG){
}
HttpsUtils.buildSSL 添加非工作时间参数
/**
* 为Lotus构建SSL证书
*在应用程序内调用时,设置在主进程内使用时必须注意,防止多进程引发异常。
*
* @param ctx 上下文必须用于检索汽车和机器的内置资源。
* @param isByWhiteList 是否以白名单模式获取证书
* @param overtime 配置超时时间。 SSLMills.MILLS_MIN 表示回调成功或失败之前不会超时。
* 其他时间仅限于SSMills,并表明此计划必须在指定时间完成操作。否则会在指定时间回调,并返回null和指定的错误码。
* @param监听器回调监听结果[SSLConst.CODE_SUC]和[SSLParams]
* */
玩得开心构建SSL(
ctx: 上下文,
isByWhiteList: 布尔值=false,
@SSLMills 加班: 长=SSLMills.MILLS_MIN,
监听器: SSL监听器
)
添加了新的错误代码SSLConst.CODE_CONTEXT_ERROR。如果无法通过上下文检索应用程序,则会回调此错误代码以优化lib 结构并使用单个构建作为任务的请求。扩展版本号可以从3 更改为4。后续的错误修复和更新更改了最后一个(不影响访问的)版本号,该版本号在添加新方法或参数时会发生变化。仅当计划发生重大变化时才会对第二个数字进行更改。
V1.3.0
该内容目前无法显示在文档之外
将HttpsUtils.buildSSL 方法体中的回调更改为SSLListener 接口中的回调,这样就可以在不引入kotlin 依赖的情况下集成Java 端。
//TODO: 根据需要传入白名单方法或系统方案配置。需要注意的是,该应用不支持同时获取白名单和系统方案双向认证配置,之前的成功构建优先。
HttpsUtils.buildSSL(ctx, true, 监听器=对象: SSLListener {
覆盖fun 回调(code: Int, ssl: SSLParams?) {
SSLLogUtils.d(TAG, \’buildSSL–code:$code;ssl:$ssl\’)
}
})
修改HttpsUtils.buildSSL 中的构建规则,以允许同时多次检索同一方案的配置。这意味着您的应用程序只能获取白名单或系统方案双向身份验证配置来支持单个主机。或aar,需要多个插件或实现aar双向认证功能,但主机或AAR无法控制调用时序。删除对本地资源配置的支持。该演示提供SSLSocketUtils 来显示检索双向身份验证配置逻辑的重试、监视双向身份验证配置、检索结果并创建以下网络请求逻辑。 HttpsUtils.buildSSL 已更改为仅支持主线程调用。新错误代码SSLConst.CODE_THREAD_ERROR。非主线程调用HttpsUtils.buildSSL 方法时会回调该错误码。
V1.2.1
暂时不可能
在文档外展示此内容
callback新增错误码回调将老的callback标记为过时的,待后续版本更新将进行废除
/**
* 构建路特斯的ssl认证
* 如果是在Application中调用,需要注意配置在主进程中使用,防止多进程导致异常
*
* @param ctx 获取车机端内置资源需要使用context
* @param overTime 配置超时时间,为 SSLMills.MILLS_MIN表示没有超时直到回调成功或失败;
* 其它限定在SSLMills的时间,表示此方案需要在指定时间完成操作,否证就会在到达指定时间回调null,并停止执行
* @param isByWhiteList 是否通过白名单模式获取证书
* @param callbackDeprecated 回调双向认证所需要的资源,为null表示构建失败,在v1.3.0之后已被callback替代
* @param code 错误码
* @see SSLConst.CODE_SUC
* @param ssl 双向认证所需要的资源,为null表示构建失败
* */
private fun buildSSL(
ctx: Context,
@SSLMills overTime: Long = SSLMills.MILLS_MIN,
isByWhiteList: Boolean = false,
callbackDeprecated: ((
ssl: SSLParams?
) -> Unit)? = null,
callback: ((
code: Int,
ssl: SSLParams?
) -> Unit)? = null
)
V1.2.0
暂时无法在文档外展示此内容
新增白名单方案
/**
* 构建路特斯的ssl认证
* 如果是在Application中调用,需要注意配置在主进程中使用,防止多进程导致异常
*
* @param ctx 获取车机端内置资源需要使用context
* @param overTime 配置超时时间,为 SSLMills.MILLS_MIN表示没有超时直到回调成功或失败;
* 其它限定在SSLMills的时间,表示此方案需要在指定时间完成操作,否证就会在到达指定时间回调null,并停止执行
* @param isByWhiteList 是否通过白名单模式获取证书
* @param callback 回调双向认证所需要的资源,为null表示构建失败
* */
fun buildSSL(
ctx: Context,
@SSLMills overTime: Long = SSLMills.MILLS_MIN,
isByWhiteList: Boolean = false,
callback: (
ssl: SSLParams?
) -> Unit
)
Demo新增HostnameVerifierUtils用来对证书中的Host进行严格校验过滤短时间多次调用获取证书方法导致的问题冗余重载HttpsUtils.buildSSL,以供java端使用时不用填充各个参数
V1.1.0
暂时无法在文档外展示此内容
HttpsUtils.buildSSL新增超时时间配置
/**
* 构建路特斯的ssl认证
* 如果是在Application中调用,需要注意配置在主进程中使用,防止多进程导致异常
*
* @param ctx 获取车机端内置资源需要使用context
* @param overTime 配置超时时间,为 SSLMills.MILLS_MIN表示没有超时直到回调成功或失败;
* 其它限定在SSLMills的时间,表示此方案需要在指定时间完成操作,否证就会在到达指定时间回调null,并停止执行
* @param callback 回调双向认证所需要的资源,为null表示构建失败
* */
fun buildSSL(
ctx: Context,
@SSLMills overTime: Long = SSLMills.MILLS_MIN,
callback: (ssl: SSLParams?) -> Unit
)
HttpsUtils.buildSSL修改callback回调线程,指定为UI线程统一lib日志打印工具为SSLLogUtils,SSLLogUtils.isLogEnable由开发者配置是否打印lib中的日志proguard-rules配置增加保留包名,以防止与开发者的其他依赖混淆冲突支持本地资源配置
V1.0.0
第一个正式发布的release版本,提供双向认证和自定义双向认证方案。
Maven依赖
首先在项目的根目录下的build.gradle中配置
maven {
url \”https://nexus-cockpit.lotuscars.com.cn/repository/maven-releases/\”
}
maven {//不使用snapshot版本的情况,不需要引入
url \”https://nexus-cockpit.lotuscars.com.cn/repository/maven-snapshots/\”
}
其次在需要使用的module的bulid.gradle配置
implementation \”com.lotus.ssl:ssllib:$sslVersion\”//配置指定的版本号即可,如1.6.0
ISSUE
首先先按照文档中 Q&A 进行证书问题排查,确认不是车机证书不存在导致的问题;其次按照 常见问题 进行排查,确认不属于已有问题。
最后 提供车机或台架系统版本信息、集成的应用的manifest文件截图、车机或台架查询证书的命令后的执行结果截图,以及开启 lib库的日志(SSLLogUtils中存在开关控制)提供完整日志以供分析。
需要aar包或者源码的朋友,可以在评论区留下联系方式,我会第一时间发给你
#以上关于车载双向认证框架设计的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92273.html