This needs to use crypto/subtle for digest comparisons to avoid timing attacks.