使用提供的公钥验证ECDSA签名

I'm trying to write a verifier for some custom jwt-like logic in go. I'm unsure of how to use the ecdsa verify method. What do r and s represent and how to I populate these from a provided signature? I have the following so far but I'm not sure if it's even close.

sig := "MEUCIQDLUXOWIw8xuJ1pALV8qeao0ZCBFjBnGLzY_RP-2Y5hdwIgQgB4skfOppPTsuDicJ1O25S50MokqtlQKrXSrnoDEVE"

hasher := crypto.Hash.New(crypto.SHA512)
hasher.Write([]byte(j))

r := new(big.Int).SetBytes(signature[:len(signature)/2])
s := new(big.Int).SetBytes(signature[len(signature)/2:])

verify := ecdsa.Verify(publicKey, hasher.Sum(nil), r, s)

r and s are just two numbers representing the signature. Asymmetric crypto is just large numbers after all. You can find a description of the verification algorithm here.

How those two numbers are serialized and encoded is what really matters. If the signed just concatenated the raw bytes of the Sign outputs r and s, your proposal would be correct.

However, the string you show look like it is encoded in url-safe base64. You would need to decode it first, then split it (or maybe split, then decode). Without knowing how the signer chose to represent the signature, we can't tell.

Dealing with jwt (or crypto in general) means knowing exactly how everything is encoded/represented. Instead of rolling out your own, you should use something like jwt-go which has ecdsa signature verification. Their ecdsa verification should be a good starting point if you want to roll your own.

If you look at ecdsa.PrivateKey.Sign() source, you'll find this at the very end:

return asn1.Marshal(ecdsaSignature{r, s})

So you should asn1.Unmarshal to get original numbers. Unfortunally, ecdsa package neither have such method, nor export ecdsaSignature struct. So you should copy-paste it. In Go you can use unnamed struct:

var esig struct {
    R, S *big.Int
}
if _, err := asn1.Unmarshal(sig, &esig); err != nil {
    return err
}
verify := ecdsa.Verify(publicKey, hasher.Sum(nil), esig.R, esig.S)

I've found this solution here: https://swenotes.wordpress.com/2018/04/16/trying-to-learn-ecdsa-and-golang/