全部产品
云市场

4.1,ID²-km在Link Kit SDK v2.3.0适配

更新时间:2019-10-18 12:14:51

适用范围:

  • 使用Link kit SDK v2.3.0 、安全SDK v0.5集成安全功能(包括ID²、iTLS)
  • 通过物联网平台创建的产品,节点类型为:网关类型、设备类型。

最佳实践说明:
1,本文所使用的产品,节点类型:网关类型;
2,网关设备下挂的子设备,通过设备证书(三元组)的方式进行认证;

1,编译Link kit SDK

下载Link Kit SDK v2.3.0,推荐使用v2.3.0版本,

1.2,配置编译选项

通过 make menuconfig进入编译配置,编译选项中,使能 iTLS 和 网关example,

  • 使能iTLS:

  • 使能gateway:

1.3,配置PK、PS

修改gateway example code,把ProductKey,Product Secret按照步骤1.2中的值进行替换。
Device Name,Device Secret可以自行命名,保证unique每个设备唯一即可。

  1. $ vim examples/linkkit/linkkit_example_gateway.c

1.4,集成安全SDK库

如果您是针对嵌入式设备平台进行开发集成,那么请联系IoT安全团队沟通提供相关平台的安全库。

2,集成安全SDK

2.1,集成 安全sdk v0.5

如果您直接使用ubuntu,那么可以确认下Linkkit C-SDK里面prebuilt目录下已经包含了预编译好的安全SDK库,这样您可以进行自行编译集成:

prebuilt/

│├── ubuntu

│ ├── bin

│ │ └── kconfig-mconf

│ ├── include

│ └── libs

│ ├── libalicrypto.a

│ ├── libcurl.a

│ ├── libID²client.a

│ ├── libitls.a

│ ├── libkm.a

│ ├── libmbedcrypto.a

│ └── libplat_gen.a

2.2.1 Linkkit接口框图

linkkit整体框图
image.png
安全sdk 调用框图
image.png

2.2.2 集成安全sdk 相关库

用安全相关库复制到prebuilt/$(os_name)/libs底下, 复制完之后,prebuilt/$(os_name)/libs底下的库为:
libicrypto.a libid2.alibitls.a libkm.a libls_hal.alibls_osa.a
其中libicrypto.a libid2.a libitls.a libkm.a 为安全团队提供的库, libls_osa.alibls_hal.a 为厂商适配的osa 及hal 层库。

2.2.3 切换tls 的方式为itls 连接方式

make menuconfig
image.png

2.2.4 修改示例代码,编译并运行example

修改PRODUCT_KEY 和 PRODUCT_SECRET 为产品的PRODUCT_KEY 和 PRODUCT_SECRET, DEVICE_NAME 保证产品唯一即可, DEVICE_SECRET 可以为任意值。
image.png

修改iotkit-embedded/examples/iot.mk 链接选项中添加安全相关库依赖
image.png
修改iotkit-embedded/src/ref-impl/hal/os/$os_name /HAL_Crypt_Linux.c, 适配alicrypto 的接口。
参考代码实现如下:

  1. #include "iot_import.h"
  2. #include "ali_crypto.h"
  3. #define AES_BLOCK_SIZE 16
  4. #define KEY_LEN 16 // aes 128 cbc
  5. #define p_aes128_t p_HAL_Aes128_t
  6. #define PLATFORM_AES_ENCRYPTION HAL_AES_ENCRYPTION
  7. #define PLATFORM_AES_DECRYPTION HAL_AES_DECRYPTION
  8. p_HAL_Aes128_t HAL_Aes128_Init(
  9. _IN_ const uint8_t *key,
  10. _IN_ const uint8_t *iv,
  11. _IN_ AES_DIR_t dir)
  12. {
  13. ali_crypto_result result;
  14. void * aes_ctx;
  15. size_t aes_ctx_size, alloc_siz;
  16. uint8_t * p;
  17. bool is_en = true; // encrypto by default
  18. if (dir == PLATFORM_AES_DECRYPTION) {
  19. is_en = false;
  20. }
  21. result = ali_aes_get_ctx_size(AES_CBC, &aes_ctx_size);
  22. if (result != ALI_CRYPTO_SUCCESS) {
  23. HAL_Printf("get ctx size fail(%08x)", result);
  24. return NULL;
  25. }
  26. alloc_siz = aes_ctx_size + KEY_LEN * 2 + sizeof(bool);
  27. aes_ctx = HAL_Malloc(alloc_siz);
  28. if (aes_ctx == NULL) {
  29. HAL_Printf("kmalloc(%d) fail", (int)aes_ctx_size);
  30. return NULL;
  31. }
  32. memset(aes_ctx, 0, alloc_siz);
  33. p = (uint8_t *)aes_ctx + aes_ctx_size;
  34. memcpy(p, key, KEY_LEN);
  35. p += KEY_LEN;
  36. memcpy(p, iv, KEY_LEN);
  37. p += KEY_LEN;
  38. *((bool *)p) = is_en;
  39. return aes_ctx;
  40. }
  41. int HAL_Aes128_Destroy(_IN_ p_HAL_Aes128_t aes)
  42. {
  43. if (aes) {
  44. HAL_Free(aes);
  45. }
  46. return 0;
  47. }
  48. static int platform_aes128_encrypt_decrypt(p_HAL_Aes128_t aes_ctx,
  49. const void *src, size_t siz,
  50. void *dst, aes_type_t t)
  51. {
  52. ali_crypto_result result;
  53. size_t dlen, in_len = siz, ctx_siz;
  54. uint8_t * p, *key, *iv;
  55. bool is_en;
  56. if (aes_ctx == NULL) {
  57. HAL_Printf("platform_aes128_encrypt_decrypt aes_ctx is NULL");
  58. return -1;
  59. }
  60. result = ali_aes_get_ctx_size(AES_CBC, &ctx_siz);
  61. if (result != ALI_CRYPTO_SUCCESS) {
  62. HAL_Printf("get ctx size fail(%08x)", result);
  63. return 0;
  64. }
  65. p = (uint8_t *)aes_ctx + ctx_siz;
  66. key = p;
  67. p += KEY_LEN;
  68. iv = p;
  69. p += KEY_LEN;
  70. is_en = *((uint8_t *)p);
  71. in_len <<= t == AES_CBC ? 4 : 0;
  72. dlen = in_len;
  73. result = ali_aes_init(t, is_en, key, NULL, KEY_LEN, iv, aes_ctx);
  74. if (result != ALI_CRYPTO_SUCCESS) {
  75. HAL_Printf("ali_aes_init fail(%08x)", result);
  76. return 0;
  77. }
  78. result = ali_aes_finish(src, in_len, dst, &dlen, SYM_NOPAD, aes_ctx);
  79. if (result != ALI_CRYPTO_SUCCESS) {
  80. HAL_Printf("aes_finish fail(%08x)", result);
  81. return -1;
  82. }
  83. return 0;
  84. }
  85. int HAL_Aes128_Cbc_Encrypt(
  86. _IN_ p_HAL_Aes128_t aes,
  87. _IN_ const void *src,
  88. _IN_ size_t blockNum,
  89. _OU_ void *dst)
  90. {
  91. return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);
  92. }
  93. int HAL_Aes128_Cbc_Decrypt(
  94. _IN_ p_HAL_Aes128_t aes,
  95. _IN_ const void *src,
  96. _IN_ size_t blockNum,
  97. _OU_ void *dst)
  98. {
  99. return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);
  100. }
  101. int HAL_Aes128_Cfb_Encrypt(
  102. _IN_ p_HAL_Aes128_t aes,
  103. _IN_ const void *src,
  104. _IN_ size_t length,
  105. _OU_ void *dst)
  106. {
  107. return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);
  108. }
  109. int HAL_Aes128_Cfb_Decrypt(
  110. _IN_ p_HAL_Aes128_t aes,
  111. _IN_ const void *src,
  112. _IN_ size_t length,
  113. _OU_ void *dst)
  114. {
  115. return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);
  116. }

运行make, 编译成功后,运行iotkit-embedded/output/release/bin 文件夹下的mqtt-example,出现以下log信息表示已成功切换成itls的链接方式,
image.png
出现以下log信息表示mqtt 测试成功。
image.png

2.2.5 调试

如需更多的调试log, 用debug 版本的itls 及id2 库,替换原prebuilt/ubuntu/libs 文件夹中的libitls.a 和libid2.a.
修改src/ref-impl/hal/ssl/itls/HAL_TLS_itls.c, 在该文件中添加宏定义MBEDTLS_DEBUG_C, 并将DEBUG_LEVEL 修改为4, 如下所示:
-#define DEBUG_LEVEL 0
+#define MBEDTLS_DEBUG_C
+#define DEBUG_LEVEL 4
重新编译运行测试程序。

2.2.6 错误码

查看 iTLS错误码

备注:
1.上面的消息警告,是在通信过程中,服务端发生异常,主动向设备端发送的消息通告。
2.上面的消息类型,是指iTLS Native返回的警告类型,Android Linkkit接口返回的值已做加权(10000)处理。

3,编译

make编译链接生成gateway exampe程序,并且运行该网关例子程序。

  1. ./output/release/bin/linkkit-example-gw 5 auto

最后两个参数您可以手工输入,请参见实际代码。

查看日志:注意Host端口后缀为 itls.cn-shanghai.aliyuncs.com

查看日志:注意建联成功

4,验证

登录阿里云物联网平台,在“设备管理”->“设备”列表查看Device Name与(步骤3.3中)gateway example代码中设置的Device Name一致。
如果一致,则该设备已经通过ID²认证并且接入物联网平台,您可以进行后续设备topic订阅与推送等。