生成 EC 密钥并在 webauthn 中验证签名

问题描述 投票:0回答:1

我正在使用 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)

python public-key-encryption public-key webauthn
1个回答
0
投票

在 WebAuthn 中创建和压缩公钥看起来是正确的 - 一切都是为了获取密钥、压缩它并将其转换为 base64。当转向 python 进行签名验证时,请确保您正确使用

cryptography
的 EC 实用程序。关键部分是从客户端发送的 Base64 格式中提取公钥信息。如有必要,请记住将其解压缩,然后使用它以正确的算法(通常是用于 WebAuthn 的 ECDSA)验证签名。 WebAuthn 和
cryptography
的文档将是您最好的朋友,以匹配具体信息。

© www.soinside.com 2019 - 2024. All rights reserved.