private const int DEFAULT_EXPIRATION = 43200; //12 hours /// <summary> /// This method takes the required VAPID parameters and returns the required /// header to be added to a Web Push Protocol Request. /// </summary> /// <param name="audience">This must be the origin of the push service.</param> /// <param name="subject">This should be a URL or a 'mailto:' email address</param> /// <param name="publicKey">The VAPID public key as a base64 encoded string</param> /// <param name="privateKey">The VAPID private key as a base64 encoded string</param> /// <param name="expiration">The expiration of the VAPID JWT.</param> /// <returns>Authorization header value.</returns> public static string GetVapidAuthenticationHeader(string audience, string subject, string publicKey, string privateKey, DateTime?expiration = null) { ValidateAudience(audience); ValidateSubject(subject); ValidatePublicKey(publicKey); ValidatePrivateKey(privateKey); if (!expiration.HasValue) { expiration = DateTime.UtcNow.AddSeconds(DEFAULT_EXPIRATION); } else { ValidateExpiration(expiration.Value); } var decodedPrivateKey = UrlBase64Encoder.Decode(privateKey); var decodedPublicKey = UrlBase64Encoder.Decode(publicKey); var privateECDsa = GetECDsaByPrivateKey(decodedPublicKey, decodedPrivateKey); //Create JWT token and sign it using ECDsa var securityToken = new JwtSecurityToken( audience: audience, claims: new[] { new Claim("sub", subject) }, expires: expiration, signingCredentials: new SigningCredentials(new ECDsaSecurityKey(privateECDsa), SecurityAlgorithms.EcdsaSha256)); var jwToken = new JwtSecurityTokenHandler().WriteToken(securityToken); return($"vapid t={jwToken}, k={publicKey}"); }
public static void ValidatePublicKey(string publicKey) { if (string.IsNullOrEmpty(publicKey)) { throw new ArgumentException("Valid public key not set."); } var decodedPublicKey = UrlBase64Encoder.Decode(publicKey); if (decodedPublicKey.Length != 65) { throw new ArgumentException("Vapid public key must be 65 characters long when decoded."); } }
public static void ValidatePrivateKey(string privateKey) { if (string.IsNullOrEmpty(privateKey)) { throw new ArgumentException("Valid private key not set."); } var decodedPrivateKey = UrlBase64Encoder.Decode(privateKey); if (decodedPrivateKey.Length != 32) { throw new ArgumentException("Vapid private key should be 32 bytes long when decoded."); } }