为物联网设备自动生成全局唯一标识的最佳方法

huangapple go评论92阅读模式
英文:

Best way to auto generate global unique identity for IoT devices

问题

我有一个使用Golang开发的应用程序,用于与MQTT通信的物联网设备,该应用程序还可以安装在支持Docker和Golang的任何设备上。

现在,当我在设备上首次运行我的应用程序时,我希望为每个设备自动生成唯一的身份标识。我考虑使用永久MAC地址或序列号,这种方法可行吗?所有设备都有永久的MAC地址或序列号吗?如果没有,那么有什么更好的方法来实现这一点呢?

英文:

I have a application developed in Golang for IoT devices which communicates over MQTT, and this application can also be installed on any device that supports Docker and Golang.

Now I want to auto generate unique identity for my application for each device when I run my application for first time on a device.
I was thinking about using permanent MAC or Serial Number, is that good approach and will all device have permanent MAC or Serial Number? If not then what is the better way to achieve this.

答案1

得分: 2

尝试从以下代码中获取一些灵感:

package main

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"time"
)

// 使用SHA1算法进行哈希
func SHA1(text string) string {
	algorithm := sha1.New()
	algorithm.Write([]byte(text))
	return hex.EncodeToString(algorithm.Sum(nil))
}

func main() {
	var macAddress = "00:00:00:00:00:00"
	var deviceType = "deviceType"
	var deviceName = "deviceName"
	var deviceModel = "deviceModel"
	var deviceManufacturer = "deviceManufacturer"
	var deviceVersion = "deviceVersion"
	var deviceSerialNumber = "deviceSerialNumber"
	var timeInMilliseconds = time.Now().UnixNano() / int64(time.Millisecond)
	// 将时间转换为字符串
	var timeString = fmt.Sprintf("%d", timeInMilliseconds)
	var conc = macAddress + "-" + deviceType + "-" + deviceName + "-" + deviceModel + "-" + deviceManufacturer + "-" + deviceVersion + "-" + deviceSerialNumber + "-" + timeString

	// 使用SHA1算法和连接后的字符串计算UUID
	var uuid = SHA1(conc)
	fmt.Println(uuid)
}
  • MAC地址主要由设备制造商分配,因此通常被称为烧录地址、以太网硬件地址、硬件地址或物理地址。
  • 序列号允许公司识别产品并获取有关其替换或寻找兼容零件的其他信息。
英文:

Try to get some inspiration from the following code:

package main

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"time"
)

// SHA1 hashes using sha1 algorithm
func SHA1(text string) string {
	algorithm := sha1.New()
	algorithm.Write([]byte(text))
	return hex.EncodeToString(algorithm.Sum(nil))
}

func main() {
	var macAddress = "00:00:00:00:00:00"
	var deviceType = "deviceType"
	var deviceName = "deviceName"
	var deviceModel = "deviceModel"
	var deviceManufacturer = "deviceManufacturer"
	var deviceVersion = "deviceVersion"
	var deviceSerialNumber = "deviceSerialNumber"
	var timeInMilliseconds = time.Now().UnixNano() / int64(time.Millisecond)
	// convert time to string
	var timeString = fmt.Sprintf("%d", timeInMilliseconds)
	var conc = macAddress + "-" + deviceType + "-" + deviceName + "-" + deviceModel + "-" + deviceManufacturer + "-" + deviceVersion + "-" + deviceSerialNumber + "-" + timeString

	// calculate the uuid using the sha256 algorithm
	// and the concatenated string
	var uuid = SHA1(conc)
	fmt.Println(uuid)

}

  • MAC addresses are primarily assigned by device manufacturers, and are therefore often referred to as the burned-in address, or as an Ethernet hardware address, hardware address, or physical address.
  • A serial number allows a company to identify a product and get additional information about it for replacement or to find compatible parts

答案2

得分: 1

读取一些加密随机数据。将随机数据转换为字符串。

// N 是要读取的随机数据的字节数。
// 我设置为 N,与 UUID 中的字节数相同。
const N = 16

p := make([]byte, N)
if _, err := rand.Read(p); err != nil {
    // TODO: 处理错误
}
id := fmt.Sprintf("%x", p)
英文:

Read some crypto random data. Convert the random data to a string.

  // N is number of bytes of random data to 
  // to read. I set to N, the same number of 
  // bytes in a UUID.
  const N = 16

  p := make([]byte, N)
  if _, err := rand.Read(p); err != nil {
      // TODO: handle error
  }
  id := fmt.Sprintf("%x", p)

答案3

得分: 1

无法保证您的设备是否具有序列号或MAC地址,更不用说唯一的了。

关于序列号,每个设备制造商都有自己的做法。那些具有软件可访问序列号的设备通常将其烧录到某个EEPROM中,需要特殊工具才能读取。您需要了解每个目标设备的程序并运行相应的工具。

关于MAC地址,如果您的设备具有WiFi或以太网接口,那么制造商可能已为其分配了全球唯一的MAC地址。然而,您需要找到相关的网络接口并读取其MAC地址。这可能相当麻烦,因为您需要发现网络接口的系统,确定它是否是物理接口(而不是虚拟接口,如拨号、桥接、VPN等),并读取其MAC地址。最后,有些设备根本没有任何物理WiFi或以太网接口-它们可能配备了GSM模块、LoRA或其他完全不同的东西。

我建议不要依赖MAC或序列号。在首次启动时生成自己的GUID,将其存储在配置中,并在后续的标识中使用它。

附注-我假设您的目标是运行Linux或其他桌面操作系统的较大设备。微控制器通常不支持Go,当然也不支持Docker。

英文:

There's absolutely no guarantee that your device will even have have a serial number or MAC address, not to mention a unique one.

Regarding serials, every device manufacturer does its own thing. Those devices that have software-accessible serial numbers usually have them burnt into an EEPROM somewhere which requires special tools to read it. You'd need to know the procedure and run tools for each device you target.

Regarding MACs, if your device has a WiFi or Ethernet interface then the manufacturer probably has allocated a globally unique MAC address for it. However, it would be up to you to find the relevant network interface and read its MAC address. This would be rather cumbersome as you'd have to discover the system for network interfaces, determine if it's a physical interface (vs a virtual one like dial-up, bridge, vpn, etc) and read its MAC. Finally, some devices don't have any physical WiFi or Ethernet interfaces at all - they may come with a GSM module or LoRA or something else entirely.

I'd recommend not relying on MAC or serial. Generate your own GUID on first launch, store it in configuration and use it for subsequent identification.

PS - I'm assuming that you're targeting somewhat larger devices running Linux or other desktop OS. Microcontrollers generally don't support Go, and certainly not Docker.

huangapple
  • 本文由 发表于 2021年11月19日 15:15:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/70031115.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定