private async Task VerifySignatureAsync( string[] segments, string keyId, CancellationToken cancellationToken) { byte[] hash; using (var hashAlg = SHA256.Create()) { hash = hashAlg.ComputeHash( Encoding.ASCII.GetBytes($"{segments[0]}.{segments[1]}")); } var signature = JwtUtils.Base64DecodeToBytes(segments[2]); var keys = await this.keySource.GetPublicKeysAsync(cancellationToken) .ConfigureAwait(false); var verified = keys.Any(key => #if NETSTANDARD1_5 || NETSTANDARD2_0 key.Id == keyId && key.RSA.VerifyHash( hash, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1) #elif NET45 key.Id == keyId && ((RSACryptoServiceProvider)key.RSA).VerifyHash(hash, Sha256Oid, signature) #else #error Unsupported target #endif ); if (!verified) { throw this.CreateException($"Failed to verify {this.shortName} signature."); } }
/// <summary> /// Verifies the integrity of a JWT by validating its signature. The JWT must be specified /// as an array of three segments (header, body and signature). /// </summary> private async Task VerifySignatureAsync( string[] segments, string keyId, CancellationToken cancellationToken) { byte[] hash; using (var hashAlg = SHA256.Create()) { hash = hashAlg.ComputeHash( Encoding.ASCII.GetBytes($"{segments[0]}.{segments[1]}")); } var signature = JwtUtils.Base64DecodeToBytes(segments[2]); var keys = await _keySource.GetPublicKeysAsync(cancellationToken) .ConfigureAwait(false); var verified = keys.Any(key => key.Id == keyId && key.RSA.VerifyHash( hash, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); if (!verified) { throw new FirebaseException($"Failed to verify {_shortName} signature."); } }