mbedtls:如何传输和加载 public 密钥作为原始字节
mbedtls: How to transfer and load public key as raw bytes
我想使用 public/private 密钥对(使用 secp256r1 曲线的 ECDSA)签署通过 BLE 发送到嵌入式设备的命令,并在设备上验证它们。这意味着将 public 密钥发送到嵌入式设备(在注册期间)并将 public 密钥存储在设备上。当设备收到命令时,public 密钥用于通过 mbedtls.
验证签名
为了简单高效,我认为最好从 public 键(即 x 和 y 坐标)发送和存储未压缩的 64 字节数据。
我可以在我的 Android 应用程序中生成一个密钥对并提取 public 密钥的 64 个字节,然后使用 BLE 将它们发送到设备。
但是,我还没有找到使用此 public 密钥数据来验证带有 embedtls 的签名的好方法——即将原始 64 字节加载到合适的 mbedtls_ecp_keypair结构。
我已经能够使用“mbedtls_ecp_point_read_string”进行如下操作(为简洁起见删除了错误检查):
// public_key_data is buffer containing 64 bytes (32 bytes X, 32 bytes Y).
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
mbedtls_ecp_keypair public_key;
mbedtls_ecp_keypair_init(&public_key);
mbedtls_ecp_point_init(&public_key.Q);
mbedtls_ecp_group_init(&public_key.grp);
mbedtls_ecp_group_load(&public_key.grp, MBEDTLS_ECP_DP_SECP256R1);
// Convert raw bytes of public key (public_key_data) to ASCII string (hex format).
// BytesToHexStr is C function to convert bytes to string:
char x_str[65]; // 2 x 32 bytes + 1 byte for terminating NUL
char y_str[65];
BytesToHexStr(public_key_data, x_str, ...);
BytesToHexStr(public_key_data + 32, y_str, ...);
// Get ECP point from string...
mbedtls_ecp_point_read_string(
&public_key.Q, // mbedtls_ecp_point *P,
16, // int radix,
x_str, // const char *x,
y_str // const char *y
);
mbedtls_ecdsa_from_keypair(&ecdsa, &public_key);
// Generate hash of message:
mbedtls_sha256_ret(message, message_size, hash, SHA_256);
// Verify signature:
int verify_result = mbedtls_ecdsa_read_signature(&ecdsa, hash, sizeof(hash), signature, signature_size);
// Check verify_result, clean up, etc.
然而,这似乎很麻烦。
我尝试将“mbedtls_ecp_point_read_binary”函数与我的原始 public 键一起使用,但它返回了 -20096 (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE)。 mbedtls 文档说“此函数从未签名的二进制数据中导入一个点”,但它没有提供有关数据预期格式的任何详细信息。
有没有更好的方法来使用 mbedtls 传输/存储/加载 ECDSA public 密钥数据?
我今天遇到了完全相同的问题。
最终发现 mbedtls_ecp_point_read_binary 需要未压缩 public 密钥格式的二进制数据,即 0x04 后跟 X 后跟 Y。
我想使用 public/private 密钥对(使用 secp256r1 曲线的 ECDSA)签署通过 BLE 发送到嵌入式设备的命令,并在设备上验证它们。这意味着将 public 密钥发送到嵌入式设备(在注册期间)并将 public 密钥存储在设备上。当设备收到命令时,public 密钥用于通过 mbedtls.
验证签名为了简单高效,我认为最好从 public 键(即 x 和 y 坐标)发送和存储未压缩的 64 字节数据。
我可以在我的 Android 应用程序中生成一个密钥对并提取 public 密钥的 64 个字节,然后使用 BLE 将它们发送到设备。
但是,我还没有找到使用此 public 密钥数据来验证带有 embedtls 的签名的好方法——即将原始 64 字节加载到合适的 mbedtls_ecp_keypair结构。
我已经能够使用“mbedtls_ecp_point_read_string”进行如下操作(为简洁起见删除了错误检查):
// public_key_data is buffer containing 64 bytes (32 bytes X, 32 bytes Y).
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
mbedtls_ecp_keypair public_key;
mbedtls_ecp_keypair_init(&public_key);
mbedtls_ecp_point_init(&public_key.Q);
mbedtls_ecp_group_init(&public_key.grp);
mbedtls_ecp_group_load(&public_key.grp, MBEDTLS_ECP_DP_SECP256R1);
// Convert raw bytes of public key (public_key_data) to ASCII string (hex format).
// BytesToHexStr is C function to convert bytes to string:
char x_str[65]; // 2 x 32 bytes + 1 byte for terminating NUL
char y_str[65];
BytesToHexStr(public_key_data, x_str, ...);
BytesToHexStr(public_key_data + 32, y_str, ...);
// Get ECP point from string...
mbedtls_ecp_point_read_string(
&public_key.Q, // mbedtls_ecp_point *P,
16, // int radix,
x_str, // const char *x,
y_str // const char *y
);
mbedtls_ecdsa_from_keypair(&ecdsa, &public_key);
// Generate hash of message:
mbedtls_sha256_ret(message, message_size, hash, SHA_256);
// Verify signature:
int verify_result = mbedtls_ecdsa_read_signature(&ecdsa, hash, sizeof(hash), signature, signature_size);
// Check verify_result, clean up, etc.
然而,这似乎很麻烦。
我尝试将“mbedtls_ecp_point_read_binary”函数与我的原始 public 键一起使用,但它返回了 -20096 (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE)。 mbedtls 文档说“此函数从未签名的二进制数据中导入一个点”,但它没有提供有关数据预期格式的任何详细信息。
有没有更好的方法来使用 mbedtls 传输/存储/加载 ECDSA public 密钥数据?
我今天遇到了完全相同的问题。 最终发现 mbedtls_ecp_point_read_binary 需要未压缩 public 密钥格式的二进制数据,即 0x04 后跟 X 后跟 Y。