示例#1
0
        public static EncryptionResult Encrypt(byte[] userKey, byte[] userSecret, byte[] payload)
        {
            byte[] salt = GenerateSalt(16);
            AsymmetricCipherKeyPair serverKeyPair = ECKeyHelper.GenerateKeys();

            IBasicAgreement ecdhAgreement = AgreementUtilities.GetBasicAgreement("ECDH");

            ecdhAgreement.Init(serverKeyPair.Private);

            ECPublicKeyParameters userPublicKey = ECKeyHelper.GetPublicKey(userKey);

            byte[] key             = ecdhAgreement.CalculateAgreement(userPublicKey).ToByteArrayUnsigned();
            byte[] serverPublicKey = ((ECPublicKeyParameters)serverKeyPair.Public).Q.GetEncoded(false);

            byte[] prk   = HKDF(userSecret, key, Encoding.UTF8.GetBytes("Content-Encoding: auth\0"), 32);
            byte[] cek   = HKDF(salt, prk, CreateInfoChunk("aesgcm", userKey, serverPublicKey), 16);
            byte[] nonce = HKDF(salt, prk, CreateInfoChunk("nonce", userKey, serverPublicKey), 12);

            byte[] input            = AddPaddingToInput(payload);
            byte[] encryptedMessage = EncryptAes(nonce, cek, input);

            return(new EncryptionResult
            {
                Salt = salt,
                Payload = encryptedMessage,
                PublicKey = serverPublicKey
            });
        }
        public void TestGetPublicKey()
        {
            var publicKey       = UrlBase64.Decode(TestPublicKey);
            var publicKeyParams = ECKeyHelper.GetPublicKey(publicKey);

            var importedPublicKey = UrlBase64.Encode(publicKeyParams.Q.GetEncoded(false));

            Assert.Equal(TestPublicKey, importedPublicKey);
        }
        public void TestGetPrivateKey()
        {
            var privateKey       = UrlBase64.Decode(TestPrivateKey);
            var privateKeyParams = ECKeyHelper.GetPrivateKey(privateKey);

            var importedPrivateKey = UrlBase64.Encode(privateKeyParams.D.ToByteArrayUnsigned());

            Assert.Equal(TestPrivateKey, importedPrivateKey);
        }
        public void TestGetPrivateKey()
        {
            byte[] privateKey = UrlBase64.Decode(TEST_PRIVATE_KEY);
            ECPrivateKeyParameters privateKeyParams = ECKeyHelper.GetPrivateKey(privateKey);

            string importedPrivateKey = UrlBase64.Encode(privateKeyParams.D.ToByteArrayUnsigned());

            Assert.AreEqual(TEST_PRIVATE_KEY, importedPrivateKey);
        }
        public void TestGetPublicKey()
        {
            byte[] publicKey = UrlBase64.Decode(TEST_PUBLIC_KEY);
            ECPublicKeyParameters publicKeyParams = ECKeyHelper.GetPublicKey(publicKey);

            string importedPublicKey = UrlBase64.Encode(publicKeyParams.Q.GetEncoded(false));

            Assert.AreEqual(TEST_PUBLIC_KEY, importedPublicKey);
        }
示例#6
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);
        }
        public void TestGenerateKeys()
        {
            var keys = ECKeyHelper.GenerateKeys();

            var publicKey  = ((ECPublicKeyParameters)keys.Public).Q.GetEncoded(false);
            var privateKey = ((ECPrivateKeyParameters)keys.Private).D.ToByteArrayUnsigned();

            var publicKeyLength  = publicKey.Length;
            var privateKeyLength = privateKey.Length;

            Assert.Equal(65, publicKeyLength);
            Assert.Equal(32, privateKeyLength);
        }
示例#8
0
        /// <summary>
        /// Generate vapid keys
        /// </summary>
        /// <returns></returns>
        public static VapidDetails GenerateVapidKeys()
        {
            VapidDetails results = new VapidDetails();

            AsymmetricCipherKeyPair keys = ECKeyHelper.GenerateKeys();

            byte[] publicKey  = ((ECPublicKeyParameters)keys.Public).Q.GetEncoded(false);
            byte[] privateKey = ((ECPrivateKeyParameters)keys.Private).D.ToByteArrayUnsigned();

            results.PublicKey  = UrlBase64.Encode(publicKey);
            results.PrivateKey = UrlBase64.Encode(privateKey);

            return(results);
        }
        public void TestGenerateKeysNoCache()
        {
            var keys1 = ECKeyHelper.GenerateKeys();
            var keys2 = ECKeyHelper.GenerateKeys();

            var publicKey1  = ((ECPublicKeyParameters)keys1.Public).Q.GetEncoded(false);
            var privateKey1 = ((ECPrivateKeyParameters)keys1.Private).D.ToByteArrayUnsigned();

            var publicKey2  = ((ECPublicKeyParameters)keys2.Public).Q.GetEncoded(false);
            var privateKey2 = ((ECPrivateKeyParameters)keys2.Private).D.ToByteArrayUnsigned();

            Assert.False(publicKey1.SequenceEqual(publicKey2));
            Assert.False(privateKey1.SequenceEqual(privateKey2));
        }
示例#10
0
        public void TestGenerateKeys()
        {
            AsymmetricCipherKeyPair keys = ECKeyHelper.GenerateKeys();

            byte[] publicKey  = ((ECPublicKeyParameters)keys.Public).Q.GetEncoded(false);
            byte[] privateKey = ((ECPrivateKeyParameters)keys.Private).D.ToByteArrayUnsigned();

            int publicKeyLength  = publicKey.Length;
            int privateKeyLength = privateKey.Length;

            Assert.AreEqual(65, publicKeyLength);
            Assert.AreEqual(32, privateKeyLength);

            ;
        }
        private static byte[] GetKeyingMaterial(PushSubscription subscription, AsymmetricKeyParameter applicationServerPrivateKey, byte[] applicationServerPublicKey)
        {
            IBasicAgreement ecdhAgreement = AgreementUtilities.GetBasicAgreement("ECDH");

            ecdhAgreement.Init(applicationServerPrivateKey);

            byte[] userAgentPublicKey   = UrlBase64Converter.FromUrlBase64String(subscription.GetKey(PushEncryptionKeyName.P256DH));
            byte[] authenticationSecret = UrlBase64Converter.FromUrlBase64String(subscription.GetKey(PushEncryptionKeyName.Auth));
            byte[] sharedSecret         = ecdhAgreement.CalculateAgreement(ECKeyHelper.GetECPublicKeyParameters(userAgentPublicKey)).ToByteArrayUnsigned();
            byte[] sharedSecretHash     = HmacSha256(authenticationSecret, sharedSecret);
            byte[] infoParameter        = GetKeyingMaterialInfoParameter(userAgentPublicKey, applicationServerPublicKey);
            byte[] keyingMaterial       = HmacSha256(sharedSecretHash, infoParameter);

            return(keyingMaterial);
        }
示例#12
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>
            {
                { "typ", "JWT" },
                { "alg", "ES256" }
            };

            var jwtPayload = new Dictionary <string, object>
            {
                { "aud", audience },
                { "exp", expiration },
                { "sub", subject }
            };

            var signingKey = ECKeyHelper.GetPrivateKey(decodedPrivateKey);

            var signer = new JWSSigner(signingKey);
            var token  = signer.GenerateSignature(header, jwtPayload);

            var results = new Dictionary <string, string>
            {
                { "Authorization", "WebPush " + token },
                { "Crypto-Key", "p256ecdsa=" + publicKey }
            };

            return(results);
        }
        private static HttpRequestMessage SetContent(HttpRequestMessage pushMessageDeliveryRequest, PushSubscription subscription, PushMessage message)
        {
            if (message.HttpContent is null)
            {
                pushMessageDeliveryRequest.Content = null;
            }
            else
            {
                AsymmetricCipherKeyPair applicationServerKeys = ECKeyHelper.GenerateAsymmetricCipherKeyPair();
                byte[] applicationServerPublicKey             = ((ECPublicKeyParameters)applicationServerKeys.Public).Q.GetEncoded(false);

                pushMessageDeliveryRequest.Content = new Aes128GcmEncodedContent(
                    message.HttpContent,
                    GetKeyingMaterial(subscription, applicationServerKeys.Private, applicationServerPublicKey),
                    applicationServerPublicKey,
                    CONTENT_RECORD_SIZE
                    );
            }

            return(pushMessageDeliveryRequest);
        }
        public void TestGenerateSignature()
        {
            var decodedPrivateKey = UrlBase64.Decode(TestPrivateKey);
            var privateKey        = ECKeyHelper.GetPrivateKey(decodedPrivateKey);

            var header = new Dictionary <string, object>();

            header.Add("typ", "JWT");
            header.Add("alg", "ES256");

            var jwtPayload = new Dictionary <string, object>();

            jwtPayload.Add("aud", "aud");
            jwtPayload.Add("exp", 1);
            jwtPayload.Add("sub", "subject");

            var signer = new JwsSigner(privateKey);
            var token  = signer.GenerateSignature(header, jwtPayload);

            var tokenParts = token.Split('.');

            Assert.AreEqual(3, tokenParts.Length);

            var encodedHeader  = tokenParts[0];
            var encodedPayload = tokenParts[1];
            var signature      = tokenParts[2];

            var decodedHeader  = Encoding.UTF8.GetString(UrlBase64.Decode(encodedHeader));
            var decodedPayload = Encoding.UTF8.GetString(UrlBase64.Decode(encodedPayload));

            Assert.AreEqual(@"{""typ"":""JWT"",""alg"":""ES256""}", decodedHeader);
            Assert.AreEqual(@"{""aud"":""aud"",""exp"":1,""sub"":""subject""}", decodedPayload);

            var decodedSignature       = UrlBase64.Decode(signature);
            var decodedSignatureLength = decodedSignature.Length;

            var isSignatureLengthValid = decodedSignatureLength == 66 || decodedSignatureLength == 64;

            Assert.AreEqual(true, isSignatureLengthValid);
        }
示例#15
0
        public void TestGenerateSignature()
        {
            ECPrivateKeyParameters privateKey = ECKeyHelper.GetPrivateKey(new byte[32]);

            Dictionary <string, object> header = new Dictionary <string, object>();

            header.Add("typ", "JWT");
            header.Add("alg", "ES256");

            Dictionary <string, object> jwtPayload = new Dictionary <string, object>();

            jwtPayload.Add("aud", "aud");
            jwtPayload.Add("exp", 1);
            jwtPayload.Add("sub", "subject");

            JWSSigner signer = new JWSSigner(privateKey);
            string    token  = signer.GenerateSignature(header, jwtPayload);

            string[] tokenParts = token.Split('.');

            Assert.AreEqual(3, tokenParts.Length);

            string encodedHeader  = tokenParts[0];
            string encodedPayload = tokenParts[1];
            string signature      = tokenParts[2];

            string decodedHeader  = Encoding.UTF8.GetString(UrlBase64.Decode(encodedHeader));
            string decodedPayload = Encoding.UTF8.GetString(UrlBase64.Decode(encodedPayload));

            Assert.AreEqual(@"{""typ"":""JWT"",""alg"":""ES256""}", decodedHeader);
            Assert.AreEqual(@"{""aud"":""aud"",""exp"":1,""sub"":""subject""}", decodedPayload);

            byte[] decodedSignature       = UrlBase64.Decode(signature);
            int    decodedSignatureLength = decodedSignature.Length;


            bool isSignatureLengthValid = decodedSignatureLength == 66 || decodedSignatureLength == 64;

            Assert.AreEqual(true, isSignatureLengthValid);
        }
示例#16
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);

            byte[] decodedPrivateKey = UrlBase64.Decode(privateKey);

            if (expiration == -1)
            {
                expiration = UnixTimeNow() + 43200;
            }

            Dictionary <string, object> header = new Dictionary <string, object>();

            header.Add("typ", "JWT");
            header.Add("alg", "ES256");

            Dictionary <string, object> jwtPayload = new Dictionary <string, object>();

            jwtPayload.Add("aud", audience);
            jwtPayload.Add("exp", expiration);
            jwtPayload.Add("sub", subject);

            ECPrivateKeyParameters signingKey = ECKeyHelper.GetPrivateKey(decodedPrivateKey);

            JWSSigner signer = new JWSSigner(signingKey);
            string    token  = signer.GenerateSignature(header, jwtPayload);

            Dictionary <string, string> results = new Dictionary <string, string>();

            results.Add("Authorization", "WebPush " + token);
            results.Add("Crypto-Key", "p256ecdsa=" + publicKey);

            return(results);
        }