将 IoT 设备安全连接到云端的更简单的解决方案
投稿人:DigiKey 北美编辑
2019-01-15
尽管开发人员的安全意识越来越强,但在将 IoT 设备连接到云端时,他们仍会经常不自觉地采取捷径来实现安全功能。许多情况下,在合适安全机制的复杂性、微型电池供电型 IoT 设备有限的可用内存和处理资源以及产品运输需求之间,似乎存在着无法克服的冲突。
为解决这些问题以及简化 IoT 设备安全功能的实现,Microchip Technology 和 Google 合作建立了一种方法,将 Microchip 公司的安全硬件功能与被称为 JSON Web Token (JWT) 的简单数据结构结合在一起。结果证明,这种方法可以轻松实现 IoT 设备和 Google Cloud IoT Core 服务之间的相互身份验证。
本文将介绍 IoT 设备面临的安全威胁,以及目前用于应对这一威胁的设备。本文还将阐述各种安全漏洞,以及开发人员和嵌入式系统设计人员如何使用 JWT 来弥补这些漏洞。
IoT 设备的安全漏洞
针对 IoT 设备的攻击方式多种多样,绝不仅限于大规模 IoT 部署。即便是最小的 IoT 网络,对于希望利用僵尸网络中许多单个设备的资源进行分布式拒绝服务 (DDoS) 攻击和其他攻击的黑客来说,也是一个具有吸引力的目标。因此,每一类 IoT 设备的设计人员都不可避免地要面对一项必要任务:使用基于硬件、能够阻止攻击的强大安全机制来保护其系统。
例如,使用系统内存或闪存来存储用于加密和身份验证的私钥会使 IoT 设备容易受到攻击。更糟糕的是,黑客可以窃取这些私钥并使用它们来访问 IoT 网络和连接的企业资源。
安全 IC
Microchip Technology 的 CryptoMemory 和 CryptoAuthentication IC 等专用安全器件采用基于硬件的机制,可以保护私钥和其他私密数据。这些器件中集成的 EEPROM 阵列提供安全存储功能,只有通过器件的 SPI 或 I2C 串行接口访问加密安全机制后才能连通(图 1)。因此,这些器件提供了一种简单的方法来为任何 IoT 设备设计添加安全存储和其他安全功能。
图 1:Microchip Technology 的硬件安全器件(如 AT88SC0204C CryptoMemory IC)可提供安全存储,利用集成的加密机制来保护对片载 EEPROM 的访问。(图片来源:Microchip Technology)
Microchip 的 CryptoAuthentication 系列产品(如 ATECC608A)通过支持安全设计中常用的加密算法,增强了安全存储的基础。就其硬件功能而言,该器件针对以下多种算法采用硬件加速:
- 非对称加密算法:
- FIPS186-3 椭圆曲线数字签名算法 (ECDSA)
- FIPS SP800-56A 椭圆曲线 Diffie-Hellman (ECDH)
- NIST 标准 P256 椭圆曲线加密 (ECC)
- 对称加密算法:
- SHA-256 哈希加密
- 基于哈希的信息验证代码 (HMAC) 加密
- AES-128 加密
- AES-GCM(伽罗瓦域乘法)加密
- 密钥导出函数 (KDF):
- 伪随机函数 (PRF) KDF
- 基于 HMAC 的提取和扩展 KDF (HKDF)
对于加密专家而言,这组加密功能代表了一种必需的全面机制列表,以支持用于身份验证和安全数据交换的更高级别安全协议。例如,KDF 功能提供了传输层安全 (TLS) 协议所需的基本机制,用于在数据交换会话开始之前对参与者进行身份验证。
在此协议中,TLS 会话首先从客户端向服务器发送启动安全会话的请求。服务器使用其数字证书做出响应,客户端则使用该证书来确认服务器身份。客户端以这种方式验证服务器之后,会话设置继续进行,客户端通过使用服务器的公钥来生成会话密钥,以便对使用 PRF KDF 或更强大的 HDKF 创建的一些随机值进行加密。
TLS 身份验证协议是互联网安全的基础。整个证书提供商行业被称为证书颁发机构 (CA),已经发展到可以支持这一关键的安全通信组件。各家公司可以从 CA 获得可信证书,然后将证书安装到自己的服务器上,以便支持上述标准 TLS 服务器验证协议。
对于 IoT 应用而言,如果网络广泛而深入地与企业资源相连,这种单向验证将不足以提供充分保护。例如,作为更广泛攻击的组成部分,持有欺诈性证书的黑客可能会伪装成 IoT 设备的合法服务器。
除存在风险以外,IoT 开发人员在实施 TLS 相互身份验证协议时往往还面临重重困难,因为通过 TLS 实施客户端身份验证所需的证书、密钥和软件可能超出了许多 IoT 设备的能力。通过合作,Microchip Technology 和 Google 建立了一种将 ATECC608A 功能与 JSON Web Token (JWT) 简单数据结构相结合的替代方法。结果证明,这种方法可以轻松实现 IoT 设备和 Google Cloud IoT Core 服务之间的相互身份验证。
基于 JWT 的身份验证
根据 RFC 7519 规定,JWT 是一个行业标准容器,用于收集有关准备和传输 JWT 实体的信息,该信息称为声明。JWT 结构本身包括三个部分:
- 头部,包含 JSON 名称:值对:用于给令牌签名的加密算法名称 (“alg”)(例如,使用 NIST P-256 曲线的 ECDSA 名称为“EC256”)以及令牌类型 (“typ”)(这些令牌的类型为“JWT”)
- 有效载荷,包含每项声明的 JSON 名称:值对
- 签名,它使用在头部中指定的算法对密钥以及头部和声明集进行编码,并在加密前分别单独转换为采用 base64 URL 编码的表示形式
在有效载荷或其他部分指定声明时,RFC 7519 提供了极大的灵活性。该标准甚至允许在没有签名或加密的情况下创建不安全的 JWT,在这种情况下,头部将包含算法的名称:值对 {"alg":"none"}。对于与 Google Cloud IoT Core 服务一起使用的 JWT,Google 需要签名部分以及具有三项强制声明的有效载荷,包括:
- “iat”– 创建令牌时的“签发”时间,以 ISO 8601 UTC 时间戳格式表示,即从 1970 年 1 月 1 日 00:00:00 起所经过的秒数(例如,1561896000 代表格林威治标准时间 2019 年 6 月 30 日下午 12:00:00)
- “exp”– 指定令牌到期时间的 UTC 时间戳,最多为“iat”值之后 24 小时,加上 10 分钟宽限期,以计入不同客户端和服务器之间的系统时钟偏差(例如,1561982400 代表格林威治标准时间 2019 年 7 月 1 日下午 12:00:00)
- “aud”– 包含开发人员的 Google Cloud 项目 ID 的字符串
Google 的 IoT 设备验证方案将基于 TLS 的常规服务器验证与使用 JWT 的 IoT 设备验证集于一身。其中,JWT 则采用上述那些相对简单的声明创建。要启动新会话,IoT 设备会对服务器打开安全套接字,并采用上述相同的 TLS 协议对服务器进行身份验证。
此过程的下一步将依赖 Google IoT Cloud 使用轻量级消息队列遥测传输 (MQTT) 协议执行 IoT 网络事务。利用对经过身份验证的服务器的安全套接字,IoT 设备使用其唯一的 JWT 作为登录密码,“登录”到该服务器的 MQTT 主机服务(清单 1)。
复制 /* Populate the buffer with the username */ int config_get_client_username(char* buf, size_t buflen) { if(buf && buflen) { int rv = snprintf(buf, buflen, "unused"); if(0 < rv && rv < buflen) { buf[rv] = 0; return 0; } } return -1; } /* Populate the buffer with the user's password */ int config_get_client_password(char* buf, size_t buflen) { int rv = -1; if(buf && buflen) { atca_jwt_t jwt; uint32_t ts = time_utils_get_utc(); rv = atcab_init(&cfg_ateccx08a_i2c_default); if(ATCA_SUCCESS != rv) { return rv; } /* Build the JWT */ rv = atca_jwt_init(&jwt, buf, buflen); if(ATCA_SUCCESS != rv) { return rv; } if(ATCA_SUCCESS != (rv = atca_jwt_add_claim_numeric(&jwt, "iat", ts))) { return rv; } if(ATCA_SUCCESS != (rv = atca_jwt_add_claim_numeric(&jwt, "exp", ts + 86400))) { return rv; } if(ATCA_SUCCESS != (rv = atca_jwt_add_claim_string(&jwt, "aud", config_gcp_project_id))) { return rv; } rv = atca_jwt_finalize(&jwt, 0); atcab_release(); } return rv; }
清单 1:包含在 Microchip Technology 的 Google Cloud Platform IoT Core 软件样例存储库中的一个模块,其中提供的例程生成了一个虚拟用户名和 JWT 对象,用作使用 MQTT 主机进行客户端身份验证的密码。(代码来源:Microchip Technology)
虽然 IoT 设备发送用户名作为此登录序列的一部分,但该用户名并未用于身份验证。因此,传输的是一个虚拟用户名(清单 2)。相反,IoT 设备的验证是基于作为登录密码发送的 JWT 进行的。由于 JWT 签名是头部、有效载荷和设备私钥的组合,因此 Google Cloud IoT Core 服务可以验证 JWT 是否真正来自授权设备。在此验证中,Google Cloud IoT 服务使用的是设备公钥,该公钥之前由 IoT 设备开发人员使用下述密钥管理过程存储在 Google 云中。与仅使用 TLS 相比,这种方法通过一种混合方法提供相互身份验证,从而加快了流程,同时降低了 IoT 设备的资源需求。
复制 /* Connect the MQTT Client to the host */ static int client_connect(void* pCtx) { MQTTPacket_connectData mqtt_options = MQTTPacket_connectData_initializer; struct _g_client_context* ctx = (struct _g_client_context*)pCtx; size_t buf_bytes_remaining = CLIENT_MQTT_RX_BUF_SIZE; mqtt_options.keepAliveInterval = MQTT_KEEP_ALIVE_INTERVAL_S; mqtt_options.cleansession = 1; /* Client ID String */ mqtt_options.clientID.cstring = (char*)&ctx->mqtt_rx_buf[0]; if(config_get_client_id(mqtt_options.clientID.cstring, buf_bytes_remaining)) { return MQTTCLIENT_FAILURE; } /* Username String */ mqtt_options.username.cstring = mqtt_options.clientID.cstring + strlen(mqtt_options.clientID.cstring) + 1; buf_bytes_remaining -= (mqtt_options.username.cstring - mqtt_options.clientID.cstring); if(config_get_client_username(mqtt_options.username.cstring, buf_bytes_remaining)) { return MQTTCLIENT_FAILURE; } /* Password String */ mqtt_options.password.cstring = mqtt_options.username.cstring + strlen(mqtt_options.username.cstring) + 1; buf_bytes_remaining -= (mqtt_options.password.cstring - mqtt_options.username.cstring); if(config_get_client_password(mqtt_options.password.cstring, buf_bytes_remaining)) { return MQTTCLIENT_FAILURE; } return MQTTConnect(&ctx->mqtt_client, &mqtt_options); }
清单 2:此函数取自 Microchip 软件样例存储库,展示了在初始连接阶段如何使用 JWT 对象作为密码,向 MQTT 服务器验证 IoT 设备。(代码来源:Microchip Technology)
关键促进因素
ATECC608A 及其供应链的功能是这种方法的关键促进因素。虽然任何 MCU 最终都可以从 JWT 头部和有效载荷生成加密签名,但在没有基于硬件的安全密钥存储的情况下,任何仅通过软件执行的方法仍然容易受到攻击。此外,对于许多资源有限的 IoT 设备或具有严格的响应时间要求的应用来说,“仅软件”实现所需的处理器负载和执行延迟可能会让人望而却步。最后,开发人员如果在安全算法和更高级别协议方面没有丰富的经验,将很难实现所需的软件功能。Microchip 通过其 CryptoAuthLib 库解决了这些问题(图 2)。
图 2:由于 CryptoAuthLib 使用硬件抽象层 (HAL) 将 API 函数和核心基元与底层硬件分离,因此开发人员可以面向广泛的支持设备开发软件。(图片来源:Microchip Technology)
Microchip 的 CryptoAuthLib 简化了诸如 Google JWT 身份验证协议等 IoT 安全功能的实现,将复杂的安全运算简化为一组通过 CryptoAuthLib 应用编程接口 (API) 提供的函数调用。对于 IoT 开发人员而言最重要的一点可能是,Microchip CryptoAuthLib 的核心函数可充分利用 Microchip 加密 IC(如 ATECC608A 等),加快在设计中执行安全功能的速度。例如,清单 1 中的 atca_jwt_finalize() 调用使用可用的加密设备(如 ATECC608A)来创建 JWT,用作清单 2 中的密码。这种情况下,ATECC608A 可以加快 JWT 签名的加密速度,从其集成的安全存储中读取设计的私钥,以完成上述签名创建过程。
然而,即使使用先进的软件和安全设备,但由于传统上管理密钥和证书所需的方法,IoT 设备仍然容易受到攻击。过去在设备的制造、分发甚至部署过程中,都需要在外部生成私钥并将其加载到安全的存储设备中。即使使用了硬件安全模块和安全设施,这些秘密在唯一“需要知道”它们的设备之外,其短暂存在也会构成一种安全漏洞,可能导致秘密被意外或故意暴露。通过使用 ATECC608A 的功能,Microchip 和 Google 已经在很大程度上消除了这种传统的安全漏洞。
在这种新方法中,Microchip 利用 ATECC608A 的功能生成密钥对,其中的私钥永远不会离开设备(图 3)。Microchip 然后使用一个中间证书对设备生成的公钥进行签名,该证书由客户提供并存储在 Microchip 安全设施内的安全服务器中。最后,Microchip 安全地将公钥传输到 Google Cloud IoT 设备管理器中的客户帐户,其中可以为每个设备最多存储三个公钥,以支持密钥轮换策略。部署之后的 IoT 设备可以使用 ATECC608A 的安全功能来创建上述相互身份验证过程中使用的 JWT。
图 3:Microchip Technology 和 Google Cloud IoT 的服务组合简化了密钥和证书的配置,提供了一种旨在加强 IoT 应用安全的受保护机制。(图片来源:Google)
Microchip 与 Google 之间的这项合作为开发人员完全分担了密钥管理这一关键流程方面的工作。针对自定义需求,开发人员仍可以使用 CryptoAuthLib API 函数 atcab_genkey() 实现自己的密钥管理过程,这会使 ATECC608A 生成密钥对,将私钥存储在其安全存储中,并返回相关的公钥。
要探索密钥生成和其他 ATECC608A 安全功能,开发人员可以快速建立一个围绕 Microchip SAM D21 Xplained Pro 评估套件构建的综合开发环境。SAM D21 Xplained Pro 套件基于 Microchip 的 ATSAMD21J18A 32 位 Arm® Cortex®-M0+ MCU,它可以提供由 Microchip 高级软件框架 (ASF) 驱动程序和代码模块支持的完整硬件平台。
要评估包括 ATECC608A 在内的 CryptoAuthentication 器件,开发人员只需将 CryptoAuth XPRO-B 扩展板插入 Xplained Pro 板的两个扩展针座之一即可。Microchip 提供了用于评估 CryptoAuthLib 与 ATECC608A 安全功能的样例软件。此外,开发人员可以将 Microchip ATWINC1500-XPRO Wi-Fi 扩展板插入另一个针座,以运行 Microchip 样例软件,该软件可演示本文中描述的包括 TLS 服务器验证和 JWT 设备验证在内的相互身份验证流程。
结论
虽然 IoT 应用安全提出了多种要求,但关键挑战往往还是在于实现 IoT 设备和云资源的相互身份验证。在资源有限的 IoT 系统中,传统协议可能超出可用的内存和处理资源。通过使用 Microchip Technology 的 CryptoAuthLib 库以及 ATECC608A CryptoAuthentication IC,开发人员可以基于 JSON Web Token 实施更高效的方法,实现 IoT 设备与 Google Cloud IoT 服务的安全连接。
免责声明:各个作者和/或论坛参与者在本网站发表的观点、看法和意见不代表 DigiKey 的观点、看法和意见,也不代表 DigiKey 官方政策。