Knight1/vanmoof-certificates

GitHub: Knight1/vanmoof-certificates

一款用于获取、解析和签发 VanMoof SA5 及 Series 6 智能自行车蓝牙访问证书的 Go 命令行工具。

Stars: 3 | Forks: 0

# vanmoof-certificates 一个用于获取和解析 VanMoof SA5 及 Series 6 自行车证书的 Go 工具。 该工具通过 VanMoof 的 API 进行身份验证,检索您的自行车,生成 Ed25519 密钥对,并为您的 SA5 或更新型号的自行车创建证书。 目前这包括 SA5 和 SA6 型号的自行车。具体列表为:S5、A5、Series 6、Series 6 Open。 ## 功能 - 使用 token 缓存(auth token、app token、refresh token)或用户名/密码与 VanMoof API 进行身份验证 - 从您的账户中检索并筛选 SA5 和 S6 自行车 - 通过 VanMoof 的 Vehicle Registry API 支持共享/访客自行车 - 生成 Ed25519 密钥对 - 创建和解析自行车证书 - 交互式或命令行自行车选择(通过 ID 或车架号) - 用于故障排除的 debug 模式 ## 使用与安装 请参阅 [USAGE.md](USAGE.md) ## 证书结构 VanMoof 自行车证书采用二进制格式,由一个 Ed25519 签名和其后跟随的 CBOR 编码的 payload 组成。 **密钥格式(如 crypto.go 中所用):** - **Private key**:64 字节,采用 base64 编码(Ed25519 seed 与 public key 拼接) - **Public key**:32 字节,采用 base64 编码(原始 Ed25519 public key) - **编码**:标准 base64(Go 中的 `base64.StdEncoding`) - **无额外前缀**:与某些实现不同,这里使用不带元数据的原始密钥 **重要说明:** - 某些实现可能会在 public key 前加上 `0x00` 前缀(总共 33 字节) - 这种格式同样被接受 - 来自 `ed25519.GenerateKey()` 的 private key 为 64 字节:32 字节的 seed + 32 字节的 public key ### 整体格式 ``` [64 bytes: Ed25519 Signature] + [Variable length: CBOR Payload] ``` ### 签名(64 字节) 前 64 个字节包含一个 Ed25519 签名,用于对 CBOR payload 进行加密签名: - **字节 0-31**:Ed25519 签名的 R 分量 - **字节 32-63**:Ed25519 签名的 S 分量 此签名由 VanMoof 的 Certificate Authority (CA) 创建,可以使用 CA 的 public key 进行验证,以确保证书是真实的且未被篡改。 CA 签名的 public key(从自行车的 BLE 证书中恢复,并且在所有证书中都是相同的)如下: ``` 29b1f31c07d1c63b124057ebe75a0bc0796259722e5dd9a9a9302ae2061184a0 ``` 每个解析出的证书的签名都会根据此密钥进行验证;如果不匹配, 则会标记为错误(成功时静默处理)。使用 `-debug` 运行可查看完整的验证详情。 ### CBOR Payload 结构 从第 64 字节开始,证书包含一个 CBOR 编码的 map,具有以下字段: | Key | Type | Description | Example | |-----|------|-------------|---------| | `i` | uint32 | 证书 ID | `1337` | | `f` | string | Frame Module 序列号 (AFM - Authorized Frame Module) | `"SVTBKLdddddOA"` | | `b` | string | Bike Module 序列号 (ABM - Authorized Bike Module) | `"SVTBKLdddddOA"` | | `e` | uint32 | 证书过期时间 (Unix timestamp) | `1767668550` | | `r` | uint8 | 角色/访问级别 (0-15) | `7` | | `u` | bytes[16] | 用户 UUID(不含连字符) | `uuid3` | | `p` | bytes[32] | 用户的 Ed25519 public key | 32 字节的 public key | ### 访问级别(Role 字段) `r`(角色)字段决定了证书授予的权限: | Value | Access Level | Description | |-------|--------------|-------------| | `0x00` | Guest | 只读访问 | | `0x01` | Limited Access | 受限权限 | | `0x03` | Owner | 标准所有者访问 | | `0x07` | Owner | 完全控制权(解锁、设置、固件) | | `0x0F` | Service/Admin | 用于服务/维护的扩展权限 | ### 证书绑定 证书在加密上将以下内容绑定在一起: 1. **特定自行车**:frame/bike module 序列号(`f`、`b`) 2. **证书 ID**:`i` 字段在每个证书中各不相同 3. **特定用户**:API 用户 UUID(`u`) 4. **特定 Public Key**:用户的 Ed25519 public key(`p`) 5. **访问级别**:role 字段(`r`) 6. **有效期**:过期时间戳(`e`) 当自行车验证证书时,它会检查: - Ed25519 签名是否有效(由 VanMoof CA 签署) - frame/bike module 序列号是否与这辆自行车匹配 - 证书是否已过期 - 用户的 public key 是否与证书中的匹配 ### 证书示例解析 解码后的结构: - **Signature**:`...`(64 字节) - **Certificate ID**:`1337` - **Frame Module Serial (AFM)**:`SVTBKLdddddOA` - **Bike Module Serial (ABM)**:`SVTBKLdddddOA` - **Expiry**:`1767668550`(2026 年 1 月 6 日 04:02:38 CET) - **Role**:`7`(Owner - 完全控制权) - **User UUID**:`1111111-1111-3111-1111-111111111111`(UUIDv3) - **Public Key**:`KIQtqMxZ9Vdj3YLfNgNHjUB4WN4gLtDX/FwpiyFiUMs=` ### CBOR 编码细节 Payload 使用 CBOR(Concise Binary Object Representation,RFC 8949)编码: ``` 0xa7 # Map with 7 entries 0x61 0x69 # Text string "i" 0x1a 0x00 0x02 0xa7 0x66 # uint32: 1337 (Certificate ID) 0x61 0x66 # Text string "f" 0x6d # Text string, 13 bytes "SVTBKLdddddOA" # Frame Module serial (AFM) 0x61 0x62 # Text string "b" 0x6d # Text string, 13 bytes "SVTBKLdddddOA" # Bike Module serial (ABM) 0x61 0x65 # Text string "e" 0x1a 0x69 0x5c 0x7b 0x46 # uint32: 1767668550 0x61 0x72 # Text string "r" 0x07 # uint: 7 0x61 0x75 # Text string "u" 0x50 # Byte string, 16 bytes [16 bytes: user UUIDv3] 0x61 0x70 # Text string "p" 0x58 0x20 # Byte string, 32 bytes [32 bytes: public key] ``` ### 安全说明 - 似乎没有撤销机制或公开日志。如果有人可以访问包含您自行车的 VanMoof 账户,他们就可以在您不知情的情况下生成证书。此外,这些证书是不可撤销的。因此,保护自行车安全的唯一方法就是将其锁在车库或地下室中,直到 7 天过去。 - 目前尚不清楚自行车在断电后是如何知道时间的。这可能是通过 GSM、GPS 或手机实现的。如果存在干扰器或 GPS 时间被欺骗,目前会发生什么尚不清楚。在您可以伪造较旧时间的情况下,如果自行车接受了该新时间作为“正确时间”,理论上您可以使用较旧的证书解锁自行车。 - 7 天后会发生什么?由于 VanMoof 恢复了 10 年的证书有效期,目前如果不与 VanMoof API 通信以签发新证书,就无法控制自行车(backup code 除外)。或者,可以实现一种逻辑,要求进行 2FA 才能签发有效期超过 7 天的证书。 - 此外,VanMoof 可以随时将您锁定在外。
标签:API集成, EVTX分析, Go语言, 可观测性, 密码学, 手动系统调用, 数字证书, 日志审计, 智能自行车, 物联网, 程序破解