コード例 #1
0
        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));
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        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.");
            }
        }
コード例 #6
0
        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");
            }
        }
コード例 #7
0
        /// <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);
        }