我正在使用 WebAuthn 生成公钥:
const credential: PassKeyCredential | null =
(await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions,
})) as PassKeyCredential;
if (!credential) {
throw new Error("Failed to create key pair.");
}
credentialId = credential.id;
publicKey = credential
? bytesArrayToBase64(
compressPublicKey(credential.response.getPublicKey())
)
: "";
export const compressPublicKey = (rawPublicKey) => {
const u8full = new Uint8Array(rawPublicKey);
const len = u8full.byteLength;
const u8 = u8full.slice(0, (1 + len) >>> 1); // drop `y`
u8[0] = 0x2 | (u8full[len - 1] & 0x01); // encode sign of `y` in first bit
return u8.buffer;
};
export const bytesArrayToBase64 = (bytes) =>
window.btoa(String.fromCharCode(...new Uint8Array(bytes)));
我正在使用 python 后端来尝试验证签名。
示例代码:
from cryptography.hazmat.primitives.asymmetric.ec import (
ECDSA,
SECP256R1,
EllipticCurvePublicKey,
)
# Your base64-encoded public key
api_key_base64 = "AgECAyYgASFYIMUcunT4wol35rSgGjOzouAwLGJ0cjxOOaNDWlHI"
# Decode the base64-encoded public key
api_key_bytes = base64.b64decode(api_key_base64)
public_key = EllipticCurvePublicKey.from_encoded_point(
SECP256R1(),
api_key_bytes,
)
print(public_key)
from_encoded_point 函数在
处抛出错误
Invalid EC key.
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
如何生成正确的公钥以与 EC 密钥一起使用?
rust_openssl.ec.from_public_bytes(curve, data)
在 WebAuthn 中创建和压缩公钥看起来是正确的 - 一切都是为了获取密钥、压缩它并将其转换为 base64。当转向 python 进行签名验证时,请确保您正确使用
cryptography
的 EC 实用程序。关键部分是从客户端发送的 Base64 格式中提取公钥信息。如有必要,请记住将其解压缩,然后使用它以正确的算法(通常是用于 WebAuthn 的 ECDSA)验证签名。 WebAuthn 和 cryptography
的文档将是您最好的朋友,以匹配具体信息。