private static string SecureInput(Dictionary <string, object> header, Dictionary <string, object> payload) { var encodeHeader = UrlBase64.Encode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header))); var encodePayload = UrlBase64.Encode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload))); return(string.Format("{0}.{1}", encodeHeader, encodePayload)); }
/// <summary> /// Generates a Jws Signature. /// </summary> /// <param name="header"></param> /// <param name="payload"></param> /// <returns></returns> public string GenerateSignature(Dictionary <string, object> header, Dictionary <string, object> payload) { var securedInput = SecureInput(header, payload); var message = Encoding.UTF8.GetBytes(securedInput); byte[] hashedMessage; using (var sha256Hasher = SHA256.Create()) { hashedMessage = sha256Hasher.ComputeHash(message); } var signer = new ECDsaSigner(); signer.Init(true, _privateKey); var results = signer.GenerateSignature(hashedMessage); // Concated to create signature var a = results[0].ToByteArrayUnsigned(); var b = results[1].ToByteArrayUnsigned(); // a,b are required to be exactly the same length of bytes if (a.Length != b.Length) { var largestLength = Math.Max(a.Length, b.Length); a = ByteArrayPadLeft(a, largestLength); b = ByteArrayPadLeft(b, largestLength); } var signature = UrlBase64.Encode(a.Concat(b).ToArray()); return(string.Format("{0}.{1}", securedInput, signature)); }
public static EncryptionResult Encrypt(string userKey, string userSecret, string payload) { var userKeyBytes = UrlBase64.Decode(userKey); var userSecretBytes = UrlBase64.Decode(userSecret); var payloadBytes = Encoding.UTF8.GetBytes(payload); return(Encrypt(userKeyBytes, userSecretBytes, payloadBytes)); }
/// <summary> /// Generate vapid keys /// </summary> public static VapidDetails GenerateVapidKeys() { var results = new VapidDetails(); var keys = ECKeyHelper.GenerateKeys(); var publicKey = ((ECPublicKeyParameters)keys.Public).Q.GetEncoded(false); var privateKey = ((ECPrivateKeyParameters)keys.Private).D.ToByteArrayUnsigned(); results.PublicKey = UrlBase64.Encode(publicKey); results.PrivateKey = UrlBase64.Encode(ByteArrayPadLeft(privateKey, 32)); return(results); }
public static void ValidatePrivateKey(string privateKey) { if (string.IsNullOrEmpty(privateKey)) { throw new ArgumentException(@"Valid private key not set"); } var decodedPrivateKey = UrlBase64.Decode(privateKey); if (decodedPrivateKey.Length != 32) { throw new ArgumentException(@"Vapid private key should be 32 bytes long when decoded."); } }
public static void ValidatePublicKey(string publicKey) { if (string.IsNullOrEmpty(publicKey)) { throw new ArgumentException(@"Valid public key not set"); } var decodedPublicKey = UrlBase64.Decode(publicKey); if (decodedPublicKey.Length != 65) { throw new ArgumentException(@"Vapid public key must be 65 characters long when decoded"); } }
/// <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>A dictionary of header key/value pairs.</returns> public static Dictionary <string, string> GetVapidHeaders(string audience, string subject, string publicKey, string privateKey, long expiration = -1) { ValidateAudience(audience); ValidateSubject(subject); ValidatePublicKey(publicKey); ValidatePrivateKey(privateKey); var decodedPrivateKey = UrlBase64.Decode(privateKey); if (expiration == -1) { expiration = UnixTimeNow() + 43200; } var header = new Dictionary <string, object>(); header.Add("typ", "JWT"); header.Add("alg", "ES256"); var jwtPayload = new Dictionary <string, object>(); jwtPayload.Add("aud", audience); jwtPayload.Add("exp", expiration); jwtPayload.Add("sub", subject); var signingKey = ECKeyHelper.GetPrivateKey(decodedPrivateKey); var signer = new JWSSigner(signingKey); var token = signer.GenerateSignature(header, jwtPayload); var results = new Dictionary <string, string>(); results.Add("Authorization", "WebPush " + token); results.Add("Crypto-Key", "p256ecdsa=" + publicKey); return(results); }