#google-cloud #jwt #iot #heapless #elliptic-curve #no-std

no-std google-cloud-iot-jwt

Rust 语言实现的 Google Cloud IOT Core JWT,适用于嵌入式 no_std、heapless(无分配)设备

1 个不稳定版本

0.1.1 2022年1月17日
0.1.0 2022年1月17日

#1453 in 加密学

自定义许可协议

20KB
190

google-cloud-iot-jwt

crates.io

Rust 语言实现的 Google Cloud IOT Core JWT,适用于嵌入式 no_std、heapless(无分配)设备。

特性

  • ES256 JWT 签名 - 实现了椭圆曲线 ES256 签名,因为它在生成时需要的计算资源更少,且比 RSA RS256 签名更短。
  • no_std 兼容 - 库及其所有依赖项都符合 no_std 兼容,并且可以自由用于 Rust 嵌入式应用程序。
  • heapless(无 alloc)兼容 - 库及其所有依赖项不要求堆内存分配。所有计算都使用固定大小的栈变量执行。特别感谢 heaplessufmt 的贡献者。
  • RustCrypto - 该库使用纯 Rust 编写的优质加密算法。
  • 小闪存占用 - 仅占用 49.7 KB。详细信息见下文。

安装

https://crates.io/crates/google-cloud-iot-jwt

# Cargo.toml
[dependencies]
google-cloud-iot-jwt = "0.1.1"

使用方法

  1. 控制台仪表板 获取 Google Cloud 项目名称。
  2. 生成用于 ES256 签名的 PEM sec1 格式的私钥。
  3. 获取当前的 Unix 时间戳(使用实时时钟硬件、NTP 客户端等)。时间戳容差为+-10分钟。
  4. 使用项目名称、私钥和时间戳创建 JWT ES256。
  5. 与 Google Cloud IOT Core 一起使用。

生成椭圆曲线密钥

摘自 官方 Google IOT Core 文档

可以使用以下命令生成 P-256 椭圆曲线密钥对

openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
openssl ec -in ec_private.pem -pubout -out ec_public.pem

这些命令创建了以下公钥/私钥对

  • ec_private.pem:私钥,以 sec1 PEM 字符串格式,必须在设备上安全存储并用于签名认证 JWT。
  • ec_public.pem:必须在Cloud IoT Core中存储的公钥,用于验证认证JWT的签名。

打开ec_private.pem,并使用其内容创建JWT。

生成ES256 JWT

#[cfg(test)]
mod test {
    use google_cloud_iot_jwt::create_google_jwt_es256;
    use google_cloud_iot_jwt::JWT_ES256_MAX_LENGTH;

    #[test]
    fn print_jwt() {
        // Project name from the Google Cloud Dashboard
        let project = "your_google_cloud_project_name";

        // Caution: Do not place the Private Key into your sources.
        // Flash it into your device separately and then load in your code from the flash or whatever else.
        let private_key = "\
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDMvJjBfq3YVCHHeJj8pbsGITyhoHjkwg9o+3pLZkAAWoAoGCCqGSM49
AwEHoUQDQgAE5JHMOhIYK0AwPmvWXpRz2tU4OaC9A2+j8wTPDYmDLT1C3hV5ZeWr
iuPXSxsC6gVceKszCX/sJkcgQVXVkE3nOg==
-----END EC PRIVATE KEY-----
";
        // Get current Unix timestamp in seconds (e.g. Real Timer Clock, NTP client, etc)
        let timestamp = 1642293084;

        // Create JWT
        let jwt = create_google_jwt_es256(
            project,
            private_key,
            timestamp
        ).unwrap();

        println!("JWT = {}", jwt);
        println!("Actual JWT length = {}", jwt.len());
        println!("Max possible JWT length = {}", JWT_ES256_MAX_LENGTH);
    }
}

生成的JWT是有效的

  • 从指定的时间戳 + 10 分钟(Google时间偏移参数)开始,
  • 直到指定的时间戳 + 24 小时 + 10 分钟为止,

因此,您可以将JWT存储在内存中并使用24小时。

固件大小优化

达到您的MCU闪存大小的限制了吗?没问题。

设置opt-level = "z",将固件大小减少到原始大小的50%左右。

# Cargo.toml

# See https://docs.rust-embedded.org/book/unsorted/speed-vs-size.html

[profile.dev.package.google-cloud-iot-jwt]
opt-level = "z"

# or even set z-level for all packages to optimize your debug firmware size
# [profile.dev.package."*"]
# opt-level = "z"

[profile.release]
opt-level = "z"
lto = true
panic = "abort"
debug = true

闪存内存占用

在针对STM32F3Discovery的固件中测试

  • 构建目标thumbv7em-none-eabihf
  • 发布配置
    • opt-level = "z"
    • lto = true
    • panic = "abort"
    • debug = true

使用google_cloud_iot_jwt::create_google_jwt_es256进行编译;

section               size        addr
.text                46132   0x8000194
.rodata               8580   0x800b5c8
Total = 54712 bytes

不使用google_cloud_iot_jwt::create_google_jwt_es256进行编译;

section               size        addr
.text                 3388   0x8000194
.rodata                432   0x8000ed0
Total = 3820 bytes

闪存内存占用 = 54712 - 3820 = 50892字节(49.7 KB)

许可

MIT (c) 2022 Viacheslav Dobromyslov <[email protected]>

依赖项

~4.5MB
~101K SLoC