public override PasetoSecurityToken Verify(PasetoToken token, IEnumerable <SecurityKey> signingKeys) { if (token == null) { throw new ArgumentNullException(nameof(token)); } if (signingKeys == null || !signingKeys.Any()) { throw new ArgumentNullException(nameof(signingKeys)); } var keys = signingKeys.OfType <EdDsaSecurityKey>().ToList(); if (!keys.Any()) { throw new SecurityTokenInvalidSigningKeyException($"PASETO v2 requires key of type {typeof(EdDsaSecurityKey)}"); } if (token.Version != PasetoConstants.Versions.V2) { throw new ArgumentException("Invalid PASETO version"); } if (token.Purpose != PasetoConstants.Purposes.Public) { throw new ArgumentException("Invalid PASETO purpose"); } // decode payload var payload = Base64UrlEncoder.DecodeBytes(token.EncodedPayload); if (payload.Length < 64) { throw new SecurityTokenInvalidSignatureException("Payload does not contain signature"); } // extract signature from payload (rightmost 64 bytes) var signature = new byte[64]; Buffer.BlockCopy(payload, payload.Length - 64, signature, 0, 64); // decode payload JSON var message = new byte[payload.Length - 64]; Buffer.BlockCopy(payload, 0, message, 0, payload.Length - 64); token.SetPayload(Encoding.UTF8.GetString(message)); // pack var signedMessage = PreAuthEncode(new[] { Encoding.UTF8.GetBytes(PublicHeader), message, Base64UrlEncoder.DecodeBytes(token.EncodedFooter ?? string.Empty) }); // verify signature using valid keys foreach (var publicKey in keys) { var signer = new Ed25519Signer(); signer.Init(false, publicKey.KeyParameters); signer.BlockUpdate(signedMessage, 0, signedMessage.Length); var isValidSignature = signer.VerifySignature(signature); if (isValidSignature) { return(new PasetoSecurityToken(token)); } } throw new SecurityTokenInvalidSignatureException("Invalid PASETO signature"); }
public override PasetoSecurityToken Verify(PasetoToken token, IEnumerable <SecurityKey> signingKeys) { if (token == null) { throw new ArgumentNullException(nameof(token)); } if (signingKeys == null || !signingKeys.Any()) { throw new ArgumentNullException(nameof(signingKeys)); } var keys = signingKeys.OfType <RsaSecurityKey>().ToList(); if (!keys.Any()) { throw new SecurityTokenInvalidSigningKeyException($"PASETO v1 requires key of type {typeof(RsaSecurityKey)}"); } if (token.Version != PasetoConstants.Versions.V1) { throw new ArgumentException("Invalid PASETO version"); } if (token.Purpose != PasetoConstants.Purposes.Public) { throw new ArgumentException("Invalid PASETO purpose"); } // decode payload var payload = Base64UrlEncoder.DecodeBytes(token.EncodedPayload); if (payload.Length < 256) { throw new SecurityTokenInvalidSignatureException("Payload does not contain signature"); } // extract signature from payload (rightmost 64 bytes) var signature = new byte[256]; Buffer.BlockCopy(payload, payload.Length - 256, signature, 0, 256); // decode payload JSON var message = new byte[payload.Length - 256]; Buffer.BlockCopy(payload, 0, message, 0, payload.Length - 256); token.SetPayload(Encoding.UTF8.GetString(message)); // pack var signedMessage = PreAuthEncode(new[] { Encoding.UTF8.GetBytes(PublicHeader), message, Base64UrlEncoder.DecodeBytes(token.EncodedFooter ?? string.Empty) }); // verify signature using valid keys foreach (var publicKey in keys) { try { var isValidSignature = publicKey.Rsa.VerifyData(signedMessage, signature, HashAlgorithmName.SHA384, RSASignaturePadding.Pss); if (isValidSignature) { return(new PasetoSecurityToken(token)); } } catch (Exception) { // ignored } } throw new SecurityTokenInvalidSignatureException("Invalid PASETO signature"); }