首页 > 解决方案 > .Net 中的 WebAuthN 和 BouncyCastle

问题描述

我正在为 YubiKey 和 webAuthN 进行概念验证;我想我已经完成了基本步骤,但是我在验证签名时遇到了一些问题;

有几个地方对我来说可能会出错:

1)当我执行“navigator.credentials.create”时,我得到了发送到服务器的凭据对象。

2) 在服务器上我得到 COSE 公钥;它有一个 X 和 Y 点(这是椭圆曲线加密)

3)我将 X 和 Y(32 字节 Uint8Array)转换为 Org.BouncyCastle.Math.BigInteger 我在这里遇到的一个问题是有时这些 X 和 Y 坐标会产生 NEGATIVE BigInteger(最左边的位已设置)我读到这意味着这是“前导”零字节,即 33 字节数组,字节 0 为“0” - 不确定这是否属实,但在设置第一位的情况下找不到其他指令

4)我从“navigator.credentials.get”得到断言并将其发送到服务器

5) 我使用上一步中的 X 和 Y 来构建公钥,

6) 我使用 Base64Decode 将 clientDataJSON 和authenticatorData 从断言解码为各自的ByteArrays

7) 我使用 SHA256 散列“clientDataJSON”元素

8)我构建了一个包含原始“authenticatorData”和散列“clientDataJSON”(连接)的字节数组

9) 我使用 Base64Decode 从断言中解码 Signature 元素

10) 我使用上面的公钥创建了一个 Org.BouncyCastle.Crypto.Signers.ECDsaSigner

11)我在连接的authenticatorData和ClientDataHash上使用VerifySignature。

这总是返回“FALSE”(即错误的签名)

以下是一些相关代码:

//Load the Base64 Encoded ByteArrays for the PublicKey X and Y (stored when registered)
Dim EncryptionX as Byte() = Base64Decode(SavedPublicKey.X)
Dim EncryptionY as Byte() = Base64Decode(SavedPublicKey.Y)


//Decode signature and AuthenticatorData elements from assertion
Dim Signature as Byte() = Base64Decode(Assertion.Signature)
Dim authenticatorData as Byte() = Base64Decode(Assertion.authenticatorData)


//Decode and HASH ClientDataJson element form assertion
Dim ClientDataJson as Byte() = Base64Decode(Assertion.ClientDataJson)
Dim shaHash = SHA256.Create
Dim ClientDataHash As Byte() = shaHash.ComputeHash(ClientDataJson)

//Concatenate the AuthenticatorData and ClientDataHash
Dim CombinedMessage as List(Of Byte)
CombinedMessage.AddRange(authenticatorData)
CombinedMessage.AddRange(ClientDataHash)
Dim MessageToValidate as Byte()=CombinedMessage.ToArray()


//Get the secp256r1 Curve (I think this is the correct curve for WebAuthN
Dim x9ecpPar As Org.BouncyCastle.Asn1.X9.X9ECParameters = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256r1")

Dim ECCcurve As Org.BouncyCastle.Math.EC.ECCurve = x9ecpPar.Curve

//build the "point" form the curve and the X and Y points
Dim Q As Org.BouncyCastle.Math.EC.ECPoint = ECCcurve.CreatePoint(New Org.BouncyCastle.Math.BigInteger(EncryptionX), New Org.BouncyCastle.Math.BigInteger(EncryptionY))

//Build the Public Keys from the "Q" point using ECDSA algorthim 
Dim PublicKey As Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters = New Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters("ECDSA", Q, Org.BouncyCastle.Asn1.Sec.SecObjectIdentifiers.SecP256r1)


//Get an ANS1 Input stream from the Signature ByteArray
Dim ASN1 = New Org.BouncyCastle.Asn1.Asn1InputStream(Signature)


Dim Sequence As Org.BouncyCastle.Asn1.Asn1Sequence = ASN1.ReadObject()

Dim eR As Org.BouncyCastle.Math.BigInteger = DirectCast(Sequence(0), Org.BouncyCastle.Asn1.DerInteger).PositiveValue

Dim eS As Org.BouncyCastle.Math.BigInteger = DirectCast(seq(1), Org.BouncyCastle.Asn1.DerInteger).PositiveValue

Dim signer As Org.BouncyCastle.Crypto.Signers.ECDsaSigner = New Org.BouncyCastle.Crypto.Signers.ECDsaSigner

signer.Init(False, PublicKey)
Dim SignatureGood As Boolean = signer.VerifySignature(MessageToValidate, er, es)


//**** SignatureGood  ALWAYS False *****

任何帮助是极大的赞赏!提前致谢!

标签: .netbouncycastleecdsawebauthn

解决方案


最初打算深入(如您所愿)进入 WebAuthn,我最终只是转而使用(并贡献于)这个出色的项目(https://github.com/abergs/fido2-net-lib)。至少它会有你可以参考的代码。

我可能会从这里开始:https ://github.com/abergs/fido2-net-lib/blob/master/Src/Fido2/Objects/CredentialPublicKey.cs


推荐阅读