You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Golang库上传X.509证书至Azure IoT Hub创建设备遇授权问题

问题解答

1. 是否需要手动将根CA证书添加至IoT Hub?

分两种场景:

  • 如果设备证书由Azure默认信任的公共根CA(如DigiCert、Baltimore等)签发,无需手动上传根CA,IoT Hub会自动信任这些机构的证书。
  • 如果使用自定义私有根CA(自建CA服务器签发设备证书),必须手动将根CA证书上传至IoT Hub,且完成所有权验证(将IoT Hub生成的验证文件部署到你的CA域名指定路径)。这一步是核心,否则IoT Hub会拒绝信任该CA签发的设备证书,直接触发"not Authorized"错误。

2. 如何自动完成证书上传与批量创建设备?

注意:设备端无法直接在IoT Hub创建设备,创建设备属于服务端操作,需要持有IoT Hub的管理权限(如registryWrite角色)调用API。你可以通过以下两种方式实现批量自动化:

方案一:Golang调用IoT Hub服务端API批量创建

步骤如下:

  1. 准备IoT Hub管理凭证(共享访问密钥或Azure AD令牌)。
  2. 批量读取设备清单(设备ID、对应X.509证书公钥)。
  3. 循环调用IoT Hub创建设备API,为每台设备配置X.509认证:
    • 叶证书认证:上传设备叶证书的公钥到IoT Hub设备注册表。
    • CA签名认证:无需上传叶证书,只要IoT Hub已信任根CA即可。

示例服务端代码:

package main

import (
    "context"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/iothub/armiothub"
    "crypto/sha256"
    "encoding/hex"
)

func main() {
    // 初始化Azure身份认证
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        panic(fmt.Sprintf("认证初始化失败: %v", err))
    }

    // 创建IoT Hub管理客户端
    client, err := armiothub.NewClient("<你的订阅ID>", cred, nil)
    if err != nil {
        panic(fmt.Sprintf("客户端创建失败: %v", err))
    }

    // 批量设备数据
    devices := []struct {
        DeviceID string
        CertPEM  string
    }{
        {"device-001", "<设备1证书公钥PEM>"},
        {"device-002", "<设备2证书公钥PEM>"},
    }

    // 批量创建设备
    for _, dev := range devices {
        thumbprint, err := getCertSHA256Thumbprint(dev.CertPEM)
        if err != nil {
            fmt.Printf("设备%s证书指纹生成失败: %v\n", dev.DeviceID, err)
            continue
        }

        deviceParams := armiothub.Device{
            Properties: &armiothub.DeviceProperties{
                DeviceID: &dev.DeviceID,
            },
            Authentication: &armiothub.AuthenticationMechanism{
                X509Thumbprint: &armiothub.X509Thumbprint{
                    PrimaryThumbprint: &thumbprint,
                },
            },
        }

        _, err = client.CreateOrUpdateDevice(
            context.Background(),
            "<资源组名称>",
            "<IoT Hub名称>",
            dev.DeviceID,
            deviceParams,
            nil,
        )
        if err != nil {
            fmt.Printf("设备%s创建失败: %v\n", dev.DeviceID, err)
        } else {
            fmt.Printf("设备%s创建成功\n", dev.DeviceID)
        }
    }
}

// 生成证书SHA256指纹
func getCertSHA256Thumbprint(certPEM string) (string, error) {
    block, _ := pem.Decode([]byte(certPEM))
    if block == nil || block.Type != "CERTIFICATE" {
        return "", fmt.Errorf("无效的证书PEM")
    }

    cert, err := x509.ParseCertificate(block.Bytes)
    if err != nil {
        return "", err
    }

    hash := sha256.Sum256(cert.Raw)
    return hex.EncodeToString(hash[:]), nil
}

方案二:用Azure DPS实现自动注册(适合大规模设备)

如果设备数量极多,推荐用设备预配服务(DPS):

  1. 在DPS中上传并验证你的根CA证书。
  2. 创建CA认证类型的注册组。
  3. 设备启动时调用DPS注册API,DPS会自动在关联的IoT Hub中创建设备,无需手动调用IoT Hub创建设备接口。

设备端连接代码修正

你的设备端代码需注意以下几点,避免授权失败:

  • 确保设备已在IoT Hub(或通过DPS注册)存在,且认证方式为X.509。
  • 加载的证书需包含完整链(叶证书+中间CA+根CA,公共CA可省略根CA)。
  • 证书的CN或SAN字段必须与设备ID完全一致。

修正后的设备端代码:

package main

import (
    "context"
    "crypto/tls"
    "fmt"
    "github.com/amenzhinsky/iothub/iotdevice"
    "github.com/amenzhinsky/iothub/iotdevice/iotmqtt"
)

func main() {
    deviceID := "your-device-id"
    hostname := "your-iothub.azure-devices.net"

    // 加载设备证书(含私钥和完整证书链)
    cert, err := tls.LoadX509KeyPair("device-cert.pem", "device-key.pem")
    if err != nil {
        fmt.Println("证书加载失败:", err)
        return
    }

    // 创建IoT Hub客户端
    client, err := iotdevice.NewFromX509(iotmqtt.New(), deviceID, hostname, cert)
    if err != nil {
        fmt.Println("客户端初始化失败:", err)
        return
    }

    // 连接IoT Hub
    if err := client.Connect(context.Background()); err != nil {
        fmt.Println("连接失败:", err)
        return
    }
    fmt.Println("连接成功")
}

"not Authorized"报错排查方向

  1. 自定义CA场景下,确认根CA已上传并完成所有权验证。
  2. 检查设备是否已在IoT Hub创建,且认证类型设置为X.509。
  3. 验证设备证书的CN/SAN与设备ID完全匹配。
  4. 确认证书链完整,无缺失中间CA。
  5. 检查证书是否过期或被吊销。

内容的提问来源于stack exchange,提问作者Pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:46:37