我正在为 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 *****
任何帮助是极大的赞赏!提前致谢!