Exemple #1
0
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (actionContext == null) throw new Exception("actionContext");

            // 过滤带有AllowAnonymous
            if (SkipAuthorization(actionContext)) return;

            var request = ((actionContext.Request.Properties[HttpPropertyKeys.RequestContextKey] as HttpWebRequest));

            // 分别从Query、Body、Header获取Token字符串
            const string key = "access_token";
            string token = "";
            // header
            if (actionContext.Request.Headers.Contains(key))
                token = actionContext.Request.Headers.GetValues(key).First();
            // query
            // body

            if (String.IsNullOrEmpty(token))
                actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(
                    HttpStatusCode.Forbidden, "请先登录。");

            try
            {
                var payload = new JWT().Decode<JWTPayload>(token, PassportConfig.SecretKey);
                // 检查token是否已经过期
                if (payload.exp < DateTime.UtcNow)
                    actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(
                        HttpStatusCode.Forbidden, "Token已经过期。");
            }
            catch (Exception ex)
            {
                actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(
                    HttpStatusCode.Forbidden, ex.Message);
            }
        }
Exemple #2
0
        public static int GetCurrentUserID(string cookie)
        {
            var decodedToken = JWT.Decode <JWT.Container <LoginToken> >(cookie);

            return(int.Parse(decodedToken.Data.ID));
        }
Exemple #3
0
        public void TestCertMangling()
        {
            string certString = @"MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
3yILeYQzllt/g0rKVRk=";

            X509Certificate2 c = new X509Certificate2();

            c.Import(Convert.FromBase64String(certString));
            Assert.AreEqual("[email protected], CN=www.google.com, O=\"Google, Inc\", L=Mountain View, S=California, C=US", c.Issuer);
            //Assert.AreEqual("CN=Microsoft Corporate Root CA, O=Microsoft Corporation", c.Subject);
            Assert.AreEqual("X509", c.GetFormat());
            Assert.AreEqual("1.2.840.10045.2.1", c.GetKeyAlgorithm());
            Assert.AreEqual("06052B81040022", c.GetKeyAlgorithmParametersString());
            Assert.AreEqual("ECC", c.PublicKey.Oid.FriendlyName);
            ECDiffieHellmanPublicKey certKey = CryptoUtils.ImportEccPublicKeyFromCertificate(c);
            //Console.WriteLine(certKey.ToXmlString());

            // https://blogs.msdn.microsoft.com/shawnfa/2007/01/22/elliptic-curve-diffie-hellman/
            // http://stackoverflow.com/questions/11266711/using-cngkey-to-generate-rsa-key-pair-in-pem-dkim-compatible-using-c-simi
            {
                string input = "eyJhbGciOiJFUzM4NCIsIng1dSI6Ik1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFN25uWnBDZnhtQ3JTd0RkQnY3ZUJYWE10S2hyb3hPcmlFcjNobU1PSkF1dy9acFFYajFLNUdHdEhTNENwRk50dGQxSllBS1lvSnhZZ2F5a3BpZTBFeUF2M3FpSzZ1dElIMnFuT0F0M1ZOclFZWGZJWkpTL1ZSZTNJbDhQZ3U5Q0IifQo.eyJleHAiOjE0NjQ5ODM4NDUsImV4dHJhRGF0YSI6eyJkaXNwbGF5TmFtZSI6Imd1cnVueCIsImlkZW50aXR5IjoiYWY2ZjdjNWUtZmNlYS0zZTQzLWJmM2EtZTAwNWU0MDBlNTc4In0sImlkZW50aXR5UHVibGljS2V5IjoiTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUU3bm5acENmeG1DclN3RGRCdjdlQlhYTXRLaHJveE9yaUVyM2htTU9KQXV3L1pwUVhqMUs1R0d0SFM0Q3BGTnR0ZDFKWUFLWW9KeFlnYXlrcGllMEV5QXYzcWlLNnV0SUgycW5PQXQzVk5yUVlYZklaSlMvVlJlM0lsOFBndTlDQiIsIm5iZiI6MTQ2NDk4Mzg0NH0K.4OrvYYbX09iwOkz-7_N_5yEejuATcUogEbe69fB-kr7r6sH_qSu6bxp9L64SEgABb0rU7tyYCLVnaCSQjd9Dvb34WI9EducgOPJ92qHspcpXr7j716LDfhZE31ksMtWQ";

                ECDiffieHellmanPublicKey rootKey = CryptoUtils.CreateEcDiffieHellmanPublicKey("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V");

                Console.WriteLine($"Root Public Key:\n{rootKey.ToXmlString()}");
                CngKey key = CngKey.Import(rootKey.ToByteArray(), CngKeyBlobFormat.EccPublicBlob);

                Console.WriteLine("Key family: " + key.AlgorithmGroup);
                //   "identityPublicKey": "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7nnZpCfxmCrSwDdBv7eBXXMtKhroxOriEr3hmMOJAuw/ZpQXj1K5GGtHS4CpFNttd1JYAKYoJxYgaykpie0EyAv3qiK6utIH2qnOAt3VNrQYXfIZJS/VRe3Il8Pgu9CB",

                var    newKey  = CryptoUtils.ImportECDsaCngKeyFromString("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7nnZpCfxmCrSwDdBv7eBXXMtKhroxOriEr3hmMOJAuw/ZpQXj1K5GGtHS4CpFNttd1JYAKYoJxYgaykpie0EyAv3qiK6utIH2qnOAt3VNrQYXfIZJS/VRe3Il8Pgu9CB");
                string decoded = JWT.Decode(input, newKey);
                //Assert.AreEqual("", decoded);


                //ECDsaCng t = new ECDsaCng();
                //t.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP384;
                //t.KeySize = 384;
                //byte[] test = t.Key.Export(CngKeyBlobFormat.EccPublicBlob);
                //Assert.AreEqual(test, newKey);

                //string decoded = JWT.Decode(input, t.Key);
            }

            // Private key (in reality this is not necessary since we will generate it)
            AsymmetricKeyParameter privKey     = PrivateKeyFactory.CreateKey(Base64Url.Decode("MB8CAQAwEAYHKoZIzj0CAQYFK4EEACIECDAGAgEBBAEB"));
            PrivateKeyInfo         privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey);

            byte[] derKey     = privKeyInfo.GetDerEncoded();
            CngKey privCngKey = CngKey.Import(derKey, CngKeyBlobFormat.Pkcs8PrivateBlob);


            Console.WriteLine(privKeyInfo.PrivateKeyAlgorithm.Algorithm);
            Console.WriteLine(privCngKey.Algorithm.Algorithm);

            // Public key
            ECDiffieHellmanPublicKey clientKey = CryptoUtils.CreateEcDiffieHellmanPublicKey("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEDEKneqEvcqUqqFMM1HM1A4zWjJC+I8Y+aKzG5dl+6wNOHHQ4NmG2PEXRJYhujyodFH+wO0dEr4GM1WoaWog8xsYQ6mQJAC0eVpBM96spUB1eMN56+BwlJ4H3Qx4TAvAs");

            // EC key to generate shared secret

            ECDiffieHellmanCng ecKey = new ECDiffieHellmanCng(privCngKey);

            ecKey.HashAlgorithm         = CngAlgorithm.Sha256;
            ecKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            ecKey.SecretPrepend         = new byte[128];     // Server token
            //ecKey.SecretPrepend = new byte[0]; // Server token

            Console.WriteLine(ecKey.HashAlgorithm);
            Console.WriteLine(ecKey.KeyExchangeAlgorithm);

            byte[] secret = ecKey.DeriveKeyMaterial(clientKey);

            Console.WriteLine(Package.HexDump(secret));
            Console.WriteLine(Package.HexDump(Base64Url.Decode("ZOBpyzki/M8UZv5tiBih048eYOBVPkQE3r5Fl0gmUP4=")));
            Console.WriteLine(Package.HexDump(Base64Url.Decode("DEKneqEvcqUqqFMM1HM1A4zWjJC+I8Y+aKzG5dl+6wNOHHQ4NmG2PEXRJYhujyod")));

            //Console.WriteLine(Package.HexDump(Base64Url.Decode("DEKneqEvcqUqqFMM1HM1A4zWjJC+I8Y+aKzG5dl+6wNOHHQ4NmG2PEXRJYhujyod")));
        }
Exemple #4
0
        public async Task <RedirectResult> ProcessOAuthCallback(LoginProvider provider, UserInfo userInfo)
        {
            Logger.Info($"User {userInfo.Id} - login attempt");

            var audience   = JwtAudience.Cabinet;
            var userLocale = GetUserLocale();

            // find user with this ext login
            var user = await UserManager.FindByLoginAsync(provider.ToString(), userInfo.Id);

            // exists
            if (user != null)
            {
                Logger.Info($"User {userInfo.Id} - account {user.Id} found");

                // try to sign in
                var signResult = await SignInManager.CanSignInAsync(user);

                // can't sign in
                if (!signResult)
                {
                    Logger.Info($"User {userInfo.Id} - can't sign in");

                    // load options
                    await DbContext.Entry(user).Reference(_ => _.UserOptions).LoadAsync();
                }
                else
                {
                    Logger.Info($"User {userInfo.Id} - can sign in");

                    // check rights
                    var accessRightsMask = Core.UserAccount.ResolveAccessRightsMask(HttpContext.RequestServices, audience, user);
                    if (accessRightsMask != null)
                    {
                        var agent = GetUserAgentInfo();

                        //// notification
                        //await EmailComposer.FromTemplate(await TemplateProvider.GetEmailTemplate(EmailTemplate.SignedIn, userLocale))
                        //	.ReplaceBodyTag("IP", agent.Ip)
                        //	.Initiator(agent.Ip, agent.Agent, DateTime.UtcNow)
                        //	.Send(user.Email, user.UserName, EmailQueue)
                        //;

                        // activity
                        var userActivity = CoreLogic.User.CreateUserActivity(
                            user: user,
                            type: Common.UserActivityType.Auth,
                            comment: "Signed in with social network",
                            ip: agent.Ip,
                            agent: agent.Agent,
                            locale: userLocale
                            );
                        DbContext.UserActivity.Add(userActivity);
                        await DbContext.SaveChangesAsync();

                        // tfa required
                        if (user.TwoFactorEnabled)
                        {
                            Logger.Info($"User {userInfo.Id} - 2FA required");

                            var tokenForTfa = JWT.CreateAuthToken(
                                appConfig: AppConfig,
                                user: user,
                                audience: audience,
                                area: JwtArea.Tfa,
                                rightsMask: accessRightsMask.Value
                                );
                            return(Redirect(
                                       this.MakeAppLink(audience, fragment: AppConfig.Apps.Cabinet.RouteOAuthTfaPage.Replace(":token", tokenForTfa))
                                       ));
                        }

                        // new jwt salt
                        UserAccount.GenerateJwtSalt(user, audience);
                        DbContext.SaveChanges();

                        Logger.Info($"User {userInfo.Id} - signed in");

                        // ok
                        var token = JWT.CreateAuthToken(
                            appConfig: AppConfig,
                            user: user,
                            audience: audience,
                            area: JwtArea.Authorized,
                            rightsMask: accessRightsMask.Value
                            );
                        return(Redirect(
                                   this.MakeAppLink(audience, fragment: AppConfig.Apps.Cabinet.RouteOAuthAuthorized.Replace(":token", token))
                                   ));
                    }
                    else
                    {
                        Logger.Info($"User {userInfo.Id} - hasn't rights");
                    }
                }

                Logger.Info($"User {userInfo.Id} - failure 1");

                // never should get here
                return(Redirect("/"));
            }

            // doesnt exist yet
            else
            {
                Logger.Info($"User {userInfo.Id} - account creation");

                // try create and sign in
                var cuaResult = await Core.UserAccount.CreateUserAccount(HttpContext.RequestServices, userInfo.Email);

                if (cuaResult.User != null)
                {
                    Logger.Info($"User {userInfo.Id} - account {cuaResult.User.Id} created");

                    // user created and external login attached
                    if (await CreateExternalLogin(cuaResult.User, provider, userInfo))
                    {
                        Logger.Info($"User {userInfo.Id} - external login created");

                        var accessRightsMask = Core.UserAccount.ResolveAccessRightsMask(HttpContext.RequestServices, audience, cuaResult.User);
                        if (accessRightsMask != null)
                        {
                            Logger.Info($"User {userInfo.Id} - signed in");

                            // ok
                            var token = JWT.CreateAuthToken(
                                appConfig: AppConfig,
                                user: cuaResult.User,
                                audience: audience,
                                area: JwtArea.Authorized,
                                rightsMask: accessRightsMask.Value
                                );
                            return(Redirect(
                                       this.MakeAppLink(audience, fragment: AppConfig.Apps.Cabinet.RouteOAuthAuthorized.Replace(":token", token))
                                       ));
                        }
                    }

                    Logger.Info($"User {userInfo.Id} - failure 2");

                    // failed
                    return(Redirect("/"));
                }

                Logger.Info($"User {userInfo.Id} - failure 3");

                // redirect to error OR email input
                return(Redirect(
                           this.MakeAppLink(audience, fragment: AppConfig.Apps.Cabinet.RouteEmailTaken)
                           ));
            }
        }
Exemple #5
0
        /// <summary>
        /// Packs a set of key-value pairs into an unprotected JWT token.
        /// </summary>
        /// <param name="yourdata">The set of key-value pairs you want to pack.
        /// Should be translatable into Dictionary<string, object></param>
        /// <returns></returns>
        public static string Pack(object yourdata)
        {
            string token = JWT.Encode(yourdata, null, JwsAlgorithm.none);

            return(token);
        }
 public TokenSecurityContext(IHttpContextAccessor httpContextAccessor, JWT jwt)
 {
     HttpContextAccessor = httpContextAccessor;
     JWT    = jwt;
     Claims = httpContextAccessor?.HttpContext?.User.Claims;
 }
Exemple #7
0
        public static Phoenix.Socket InitSocket(JWT jwt)
        {
            var macMonWebSocket = new MacMonWebSocket(jwt);

            return(macMonWebSocket._socket);
        }
        /// <summary>
        /// Password Based Jwe using PBES2 schemes with HMAC-SHA and AES Key Wrap using 256 bit key
        /// AES GCM Key Wrap Algorithm using 256 bit keys
        /// </summary>
        /// <param name="password"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static string Decrypt(string password, string token)
        {
            var r = JWT.Decode(token, password, JweAlgorithm.PBES2_HS512_A256KW, JweEncryption.A256GCM);

            return(r);
        }
Exemple #9
0
 /// <summary>
 /// Metodo para encriptar la cadena
 /// </summary>
 /// <param name="token">cadena a encriptar</param>
 /// <returns>cadena encriptada</returns>
 public static string Encode(string token)
 {
     byte[] keys = new Encrypted().Base64UrlDecode(ConfigurationManager.AppSettings["base64UrlDecode"].ToString());
     return(JWT.Encode(token, keys, JwsAlgorithm.HS256));
 }
Exemple #10
0
        public AuthResrcProtectedAuthorizeModel Verify(string token)
        {
            //解 Token
            string jwtDecodeValue = JWT.Decode(token,
                                               Encoding.Unicode.GetBytes(this.clientInProtectedMember.ShareKeyClientWithProtectedServer),
                                               JwsAlgorithm.HS256);
            ClientAuthorizedReqModel jwtObject = JsonConvert.DeserializeObject <ClientAuthorizedReqModel>(jwtDecodeValue);

            //加密後的合法 Url List
            List <string> encryptValueList = jwtObject.ValidUrlList;

            VerifyUrlIsInAuthorizedList(encryptValueList);


            ClientTempIdentityModel tempIdentityModel           = new ClientTempIdentityModel(this.clientInProtectedMember.ClientId, this.clientInProtectedMember.HashValue);
            string shareKeyClientAndResrcDependsAuthorizedTimes = GetTempClientSecretByAuthorizedTimes(this.clientInProtectedMember.ShareKeyClientWithProtectedServer, tempIdentityModel, this.clientInProtectedMember.CurrentTimes);
            string shareIVClientAndResrcDependsAuthorizedTimes  = GetTempClientSecretByAuthorizedTimes(this.clientInProtectedMember.ShareIVClientWithProtectedServer, tempIdentityModel, this.clientInProtectedMember.CurrentTimes);

            aesCrypter.SetKey(shareKeyClientAndResrcDependsAuthorizedTimes);
            aesCrypter.SetIV(shareIVClientAndResrcDependsAuthorizedTimes.Substring(0, 16));

            string clientAuthorizeCTCryptoDecrypt = aesCrypter.Decrypt(jwtObject.CurrentTimesCypherText);
            ClientCTCypherTextModelForAuthorize clientAuthorizeCypherTextModel = JsonConvert.DeserializeObject <ClientCTCypherTextModelForAuthorize>(clientAuthorizeCTCryptoDecrypt);


            if (GetUtcNowUnixTime() > clientAuthorizeCypherTextModel.ExpiredTime)
            {
                throw new ClientAuthorizeTokenExpiredException("Client authorized token has expired, please re-authenticate and get new token");
            }

            string protectedServerOriginalHash = this.clientInProtectedMember.HashValue;
            string doubleHashValue             = MD5Hasher.Hash(clientAuthorizeCypherTextModel.HashValue);

            if (doubleHashValue != protectedServerOriginalHash)
            {
                throw new TokenTicketCerticateException("After checkt the token ticket, the token ticket is not right, the ticket you send has been used, please re-authenticate and get new token ticket");
            }

            //確認是否能夠取得下一次授權
            if (jwtObject.CurrentTimes + 1 >= clientInProtectedMember.AuthZTimes)
            {
                throw new AuthorizeTimesHasRunOutException("The token authorzie times has run out and expired, please re-authenticate and get new token ticket");
            }

            TimesCypherTextPrimeModel clientPrimeModel = new TimesCypherTextPrimeModel()
            {
                ClientTempIdPrime = new ClientTempIdentityModel()
                {
                    ClientId  = clientInProtectedMember.ClientId,
                    HashValue = clientAuthorizeCypherTextModel.HashValue
                },
                CurrentTimes = clientInProtectedMember.CurrentTimes,
                ClientTempId = new ClientTempIdentityModel()
                {
                    ClientId  = clientInProtectedMember.ClientId,
                    HashValue = clientInProtectedMember.HashValue,
                },
            };

            string newShareKeyClientAndProtected = GetTempClientSecretByAuthorizedTimes(clientInProtectedMember.ShareKeyClientWithProtectedServer, clientPrimeModel.ClientTempId, clientInProtectedMember.CurrentTimes);
            string newShareIVClientAndProtected  = GetTempClientSecretByAuthorizedTimes(clientInProtectedMember.ShareIVClientWithProtectedServer, clientPrimeModel.ClientTempId, clientInProtectedMember.CurrentTimes).Substring(0, 16);


            aesCrypter.SetIV(newShareIVClientAndProtected);
            aesCrypter.SetKey(newShareKeyClientAndProtected);
            string cypherPrimeStr = JsonConvert.SerializeObject(clientPrimeModel);
            string newCypherTextRespClientForNextAuthZ = aesCrypter.Encrypt(cypherPrimeStr);

            AuthResrcProtectedAuthorizeModel result = new AuthResrcProtectedAuthorizeModel()
            {
                ClientId    = clientInProtectedMember.ClientId,
                PortectedId = clientInProtectedMember.ProtectedId,
                ProcessScoreCurrentTimes = (clientInProtectedMember.CurrentTimes + 1),
                ProcessScoreHashValue    = clientAuthorizeCypherTextModel.HashValue,
                ClientRespCypherText     = newCypherTextRespClientForNextAuthZ
            };

            return(result);
        }
Exemple #11
0
 private string PrepareJWTPayload(string payload)
 {
     return(JWT.Encode(payload, _factory.JWTDecodeSecret, JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512));
 }
        public async Task <LoginResponse> AuthenticateUser(string login, string password)
        {
            User user = null;

            using (var connection = new SqlConnection(_connectionString))
            {
                connection.Open();

                user = connection
                       .Query <User>(
                    "EXEC [Support-API].[dbo].[SP_Get_User] @Login = @Login",
                    new { Login = login }
                    ).FirstOrDefault();
            }

            LoginResponse response = new LoginResponse
            {
                Success = false,
                Errors  = new List <string>(),
                JWT     = string.Empty,
            };

            if (user == null)
            {
                response.Errors.Add("Invalid Username or Password");
            }
            else
            {
                Hash   currentHash = new Hash(user.Hash);
                string hash        = Hashing.GenerateHash(password, currentHash.iterations, currentHash.salt);

                if (hash == user.Hash)
                {
                    string JwtSecret = _configuration.GetValue <string>("JwtSecret");
                    var    token     = JWT.GenerateToken(user.UUID, user.Login, JwtSecret);

                    int    code       = Generator.RandomNum(111111, 999999);
                    string hashedCode = Hashing.GenerateHash(code.ToString());

                    string emailPlainTemplate = "Hello {0} {1} {2}! Your Verification Code is: {3}";
                    string emailHtmlTemplate  = "<html>" +
                                                "<body>" +
                                                "<div>" +
                                                "<h2>Support App</h3>" +
                                                "<div>Hello {0} {1} {2}!</div>" +
                                                "<div>Your Verification Code is: {3}</div>" +
                                                "</div>" +
                                                "</body>" +
                                                "</html>";

                    string          emailApiKey = _configuration.GetValue <string>("MailApiKey");
                    SingleEmailPost email       = new SingleEmailPost
                    {
                        From_Email    = "*****@*****.**",
                        From_Name     = "Support App",
                        To_Email      = user.Email,
                        To_Name       = $"{user.First_Name} {user.Middle_Name} {user.Last_Name}",
                        Subject       = "Verification Email",
                        Content_Html  = string.Format(emailHtmlTemplate, user.First_Name, user.Middle_Name, user.Last_Name, code),
                        Content_Plain = string.Format(emailPlainTemplate, user.First_Name, user.Middle_Name, user.Last_Name, code),
                    };
                    await Email.SingleEmail(email, emailApiKey);

                    Session session = _sessionManager.CreateSession(user, token, hashedCode);

                    if (token == null || session == null)
                    {
                        response.Errors.Add("Authentication Error, please contact Administrator.");
                    }
                    else
                    {
                        response.Success = true;
                        response.JWT     = token;
                    }
                }
                else
                {
                    response.Errors.Add("Invalid Username or Password");
                }
            }

            return(response);
        }
Exemple #13
0
 public static T DecodeJWtToken <T>(this string token)
 {
     return(JWT.Decode <T>(token, Encoding.UTF8.GetBytes(Configuration.Key), JwsAlgorithm.HS256, Settings));
 }
        protected void DecodeCert(McpeLogin message)
        {
            _playerInfo = new PlayerInfo();

            // Get bytes
            byte[] buffer = message.payload;

            //Log.Debug($"Unknown byte in login packet is: {message.unknown}");

            if (message.payload.Length != buffer.Length)
            {
                Log.Debug($"Wrong lenght {message.payload.Length} != {message.payload.Length}");
                throw new Exception($"Wrong lenght {message.payload.Length} != {message.payload.Length}");
            }
            // Decompress bytes

            Log.Debug("Lenght: " + message.payload.Length + ", Message: " + Convert.ToBase64String(buffer));

            MemoryStream stream = new MemoryStream(buffer);

            if (stream.ReadByte() != 0x78)
            {
                throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
            }
            stream.ReadByte();

            string certificateChain;
            string skinData;

            using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
            {
                // Get actual package out of bytes
                using (MemoryStream destination = MiNetServer.MemoryStreamManager.GetStream())
                {
                    defStream2.CopyTo(destination);
                    destination.Position = 0;
                    fNbt.NbtBinaryReader reader = new fNbt.NbtBinaryReader(destination, false);

                    try
                    {
                        var countCertData = reader.ReadInt32();
                        Log.Debug("Count cert: " + countCertData);
                        certificateChain = Encoding.UTF8.GetString(reader.ReadBytes(countCertData));
                        Log.Debug("Decompressed certificateChain " + certificateChain);

                        var countSkinData = reader.ReadInt32();
                        Log.Debug("Count skin: " + countSkinData);
                        skinData = Encoding.UTF8.GetString(reader.ReadBytes(countSkinData));
                        Log.Debug("Decompressed skinData" + skinData);
                    }
                    catch (Exception e)
                    {
                        Log.Error("Parsing login", e);
                        return;
                    }
                }
            }


            try
            {
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("Input JSON string: " + certificateChain);
                    }

                    dynamic json = JObject.Parse(certificateChain);

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"JSON:\n{json}");
                    }

                    string validationKey = null;
                    foreach (dynamic o in json.chain)
                    {
                        IDictionary <string, dynamic> headers = JWT.Headers(o.ToString());

                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug("Raw chain element:\n" + o.ToString());
                            Log.Debug($"JWT Header: {string.Join(";", headers)}");

                            dynamic jsonPayload = JObject.Parse(JWT.Payload(o.ToString()));
                            Log.Debug($"JWT Payload:\n{jsonPayload}");
                        }

                        // x5u cert (string): MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V
                        if (headers.ContainsKey("x5u"))
                        {
                            string certString = headers["x5u"];

                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug($"x5u cert (string): {certString}");
                                ECDiffieHellmanPublicKey publicKey = CryptoUtils.CreateEcDiffieHellmanPublicKey(certString);
                                Log.Debug($"Cert:\n{publicKey.ToXmlString()}");
                            }

                            // Validate
                            CngKey          newKey = CryptoUtils.ImportECDsaCngKeyFromString(certString);
                            CertificateData data   = JWT.Decode <CertificateData>(o.ToString(), newKey);

                            if (data != null)
                            {
                                if (Log.IsDebugEnabled)
                                {
                                    Log.Debug("Decoded token success");
                                }

                                if (CertificateData.MojangRootKey.Equals(certString, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    Log.Debug("Got Mojang key. Is valid = " + data.CertificateAuthority);
                                    validationKey = data.IdentityPublicKey;
                                }
                                else if (validationKey != null && validationKey.Equals(certString, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    _playerInfo.CertificateData = data;
                                }
                                else
                                {
                                    if (data.ExtraData == null)
                                    {
                                        continue;
                                    }

                                    // Self signed, make sure they don't fake XUID
                                    if (data.ExtraData.Xuid != null)
                                    {
                                        Log.Warn("Received fake XUID from " + data.ExtraData.DisplayName);
                                        data.ExtraData.Xuid = null;
                                    }

                                    _playerInfo.CertificateData = data;
                                }
                            }
                            else
                            {
                                Log.Error("Not a valid Identity Public Key for decoding");
                            }
                        }
                    }

                    //TODO: Implement disconnect here

                    {
                        _playerInfo.Username = _playerInfo.CertificateData.ExtraData.DisplayName;
                        _session.Username    = _playerInfo.Username;
                        string identity = _playerInfo.CertificateData.ExtraData.Identity;

                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Connecting user {_playerInfo.Username} with identity={identity}");
                        }
                        _playerInfo.ClientUuid = new UUID(new Guid(identity));

                        _session.CryptoContext = new CryptoContext
                        {
                            UseEncryption = Config.GetProperty("UseEncryptionForAll", false) || (Config.GetProperty("UseEncryption", true) && !string.IsNullOrWhiteSpace(_playerInfo.CertificateData.ExtraData.Xuid)),
                        };

                        if (_session.CryptoContext.UseEncryption)
                        {
                            ECDiffieHellmanPublicKey publicKey = CryptoUtils.CreateEcDiffieHellmanPublicKey(_playerInfo.CertificateData.IdentityPublicKey);
                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug($"Cert:\n{publicKey.ToXmlString()}");
                            }

                            // Create shared shared secret
                            ECDiffieHellmanCng ecKey = new ECDiffieHellmanCng(384);
                            ecKey.HashAlgorithm         = CngAlgorithm.Sha256;
                            ecKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                            ecKey.SecretPrepend         = Encoding.UTF8.GetBytes("RANDOM SECRET");                     // Server token

                            byte[] secret = ecKey.DeriveKeyMaterial(publicKey);

                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug($"SECRET KEY (b64):\n{Convert.ToBase64String(secret)}");
                            }

                            {
                                RijndaelManaged rijAlg = new RijndaelManaged
                                {
                                    BlockSize    = 128,
                                    Padding      = PaddingMode.None,
                                    Mode         = CipherMode.CFB,
                                    FeedbackSize = 8,
                                    Key          = secret,
                                    IV           = secret.Take(16).ToArray(),
                                };

                                // Create a decrytor to perform the stream transform.
                                ICryptoTransform decryptor      = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
                                MemoryStream     inputStream    = new MemoryStream();
                                CryptoStream     cryptoStreamIn = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read);

                                ICryptoTransform encryptor       = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
                                MemoryStream     outputStream    = new MemoryStream();
                                CryptoStream     cryptoStreamOut = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write);

                                _session.CryptoContext.Algorithm       = rijAlg;
                                _session.CryptoContext.Decryptor       = decryptor;
                                _session.CryptoContext.Encryptor       = encryptor;
                                _session.CryptoContext.InputStream     = inputStream;
                                _session.CryptoContext.OutputStream    = outputStream;
                                _session.CryptoContext.CryptoStreamIn  = cryptoStreamIn;
                                _session.CryptoContext.CryptoStreamOut = cryptoStreamOut;
                            }

                            var response = McpeServerExchange.CreateObject();
                            response.NoBatch         = true;
                            response.ForceClear      = true;
                            response.serverPublicKey = Convert.ToBase64String(ecKey.PublicKey.GetDerEncoded());
                            response.tokenLength     = (short)ecKey.SecretPrepend.Length;
                            response.token           = ecKey.SecretPrepend;

                            _session.SendPackage(response);

                            if (Log.IsDebugEnabled)
                            {
                                Log.Warn($"Encryption enabled for {_session.Username}");
                            }
                        }
                    }
                }

                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("Input SKIN string: " + skinData);
                    }

                    IDictionary <string, dynamic> headers = JWT.Headers(skinData);
                    dynamic payload = JObject.Parse(JWT.Payload(skinData));

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Skin JWT Header: {string.Join(";", headers)}");
                    }
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Skin JWT Payload:\n{payload.ToString()}");
                    }

                    // Skin JWT Payload:
                    //{
                    // "ClientRandomId": -1256727416,
                    // "ServerAddress": "yodamine.com:19132",
                    // "SkinData": "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Af/3/wH/9/8B//f/Af/3/wAAAP/yrmj/8q5o//KuaP/yrmj/8q5o//KuaP/yrmj/8q5o/wMCAv8B//f/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD//wAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgD/AQEB/wEBAf8BAQH//fn2//359v/9+fb//fn2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUF/wkICP8JCQn/EhIS//KuaP/yrmj/AAAA/wkJCf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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",
                    // "SkinId": "Standard_Custom"
                    //}

                    _playerInfo.ServerAddress = payload.ServerAddress;
                    _playerInfo.ClientId      = payload.ClientRandomId;

                    _playerInfo.Skin = new Skin()
                    {
                        SkinType = payload.SkinId,
                        Texture  = Convert.FromBase64String((string)payload.SkinData),
                    };
                }

                if (!_session.CryptoContext.UseEncryption)
                {
                    _session.MessageHandler.HandleMcpeClientMagic(null);
                }
            }
            catch (Exception e)
            {
                Log.Error("Decrypt", e);
            }
        }
 public AccountService(IOptions <JWT> jwt, IHttpContextAccessor httpContextAccessor)
 {
     this.jwt = jwt.Value;
     this.httpContextAccessor = httpContextAccessor;
 }
        /// <summary>
        /// AES Key Wrap Algorithm using 256 bit keys, RFC 3394
        /// AES GCM Key Wrap Algorithm using 256 bit keys
        /// </summary>
        /// <param name="secret"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static string Decrypt(byte[] secret, string token)
        {
            var r = JWT.Decode(token, secret, JweAlgorithm.A256KW, JweEncryption.A256GCM);

            return(r);
        }
Exemple #17
0
 /// <summary>
 /// Metodo para desencriptar
 /// </summary>
 /// <param name="token">cadena encriptada</param>
 /// <returns>cadena desencriptada</returns>
 public static string Decode(string token)
 {
     byte[] keys = new Encrypted().Base64UrlDecode(ConfigurationManager.AppSettings["base64UrlDecode"].ToString());
     return(JWT.Decode(token, keys, null));
 }
Exemple #18
0
 private static string Decode(string payload, RSA key)
 => JWT.Decode(payload, key, JweAlgorithm.RSA_OAEP, JweEncryption.A128CBC_HS256);
        static void Main(string[] args)
        {
            #region Variables

            OperatingSystem     os     = Environment.OSVersion;
            X509KeyStorageFlags x509KS = X509KeyStorageFlags.DefaultKeySet;

            string token = "";
            IDictionary <string, object> headers = null;
            IDictionary <string, object> payload = null;
            payload = new Dictionary <string, object>()
            {
                { "sub", "*****@*****.**" },
                { "exp", 1300819380 }
            };

            #region Keys
            byte[] secretKey = null;
            byte[] x         = null;
            byte[] y         = null;
            byte[] d         = null;

            string           privateX509Path = "";
            string           publicX509Path  = "";
            X509Certificate2 publicX509Key   = null;
            X509Certificate2 privateX509Key  = null;

            CngKey publicKeyOfCng  = null;
            CngKey privateKeyOfCng = null;
            #endregion

            #endregion

            #region Certificates

            #region RSA
            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);
            Program.PrivateX509KeyInspector("RSA", privateX509Key);
            Program.PublicX509KeyInspector("RSA", publicX509Key);
            #endregion

            #region DSA
            // https://github.com/dotnet/corefx/issues/18733#issuecomment-296723615
            privateX509Path = @"SHA256DSA.pfx";
            publicX509Path  = @"SHA256DSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test");
            publicX509Key   = new X509Certificate2(publicX509Path, "");
            Program.PrivateX509KeyInspector("DSA", privateX509Key);
            Program.PublicX509KeyInspector("DSA", publicX509Key);
            DSA privateDSA = privateX509Key.GetDSAPrivateKey();
            Program.MyWriteLine("privateDSA: " + (privateDSA == null ? "is null" : "is not null"));
            DSA publicDSA = null; // publicX509Key.GetDSAPublicKey(); // Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException
            #endregion

            #region ECDsa
            // https://github.com/dotnet/corefx/issues/18733#issuecomment-296723615
            privateX509Path = @"SHA256ECDSA.pfx";
            publicX509Path  = @"SHA256ECDSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test");
            publicX509Key   = new X509Certificate2(publicX509Path, "");
            Program.PrivateX509KeyInspector("ECDsa", privateX509Key);
            Program.PublicX509KeyInspector("ECDsa", publicX509Key);
            ECDsa privateECDsa = privateX509Key.GetECDsaPrivateKey();
            Program.MyWriteLine("privateECDsa: " + (privateECDsa == null ? "is null" : "is not null"));
            ECDsa publicECDsa = publicX509Key.GetECDsaPublicKey();
            Program.MyWriteLine("publicECDsa: " + (publicECDsa == null ? "is null" : "is not null"));
            #endregion

            #endregion

            Program.MyWriteLine("----------------------------------------------------------------------------------------------------");

            #region JWT

            #region Unsecured JWT
            // Creating Plaintext (unprotected) Tokens
            // https://github.com/dvsekhvalnov/jose-jwt#creating-plaintext-unprotected-tokens
            token = "";
            token = JWT.Encode(payload, null, JwsAlgorithm.none);
            Program.MyWriteLine("JwsAlgorithm.none: " + token);
            #endregion

            #region JWS (Creating signed Tokens)
            // https://github.com/dvsekhvalnov/jose-jwt#creating-signed-tokens

            #region HS-* family
            // HS256, HS384, HS512
            // https://github.com/dvsekhvalnov/jose-jwt#hs--family
            secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };
            token     = "";
            token     = JWT.Encode(payload, secretKey, JwsAlgorithm.HS256);
            Program.VerifyResult("JwsAlgorithm.HS256: ", token, secretKey);
            #endregion

            #region RS-* and PS-* family
            // RS256, RS384, RS512 and PS256, PS384, PS512
            // https://github.com/dvsekhvalnov/jose-jwt#rs--and-ps--family
            // X509Certificate2 x509Certificate2 = new X509Certificate2();

            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);

            token = "";
            token = JWT.Encode(payload, privateX509Key.PrivateKey, JwsAlgorithm.RS256);
            Program.VerifyResult("JwsAlgorithm.RS256: ", token, publicX509Key.PublicKey.Key);
            #endregion

            #region ES- * family
            // ES256, ES384, ES512 ECDSA signatures
            // https://github.com/dvsekhvalnov/jose-jwt#es---family

            x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
            y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
            d = new byte[] { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

            if (os.Platform == PlatformID.Win32NT)
            {
                // https://github.com/dvsekhvalnov/jose-jwt/blob/master/jose-jwt/Security/Cryptography/EccKey.cs
                privateKeyOfCng = EccKey.New(x, y, d);
                publicKeyOfCng  = EccKey.New(x, y);

                token = "";
                token = JWT.Encode(payload, privateKeyOfCng, JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256: ", token, publicKeyOfCng);
            }
            else // == PlatformID.Unix
            {
                // (x, y, d)を使用して、ECCurveからECDsaOpenSslを生成できれば...。

                //ECCurve eCCurve = new ECCurve();
                ////eCCurve.A = x;
                ////eCCurve.B = y;
                ////ECDsaOpenSsl ecd = new ECDsaOpenSsl(eCCurve);
                ////eCCurve = ecd.ExportExplicitParameters(true).Curve;

                //token = "";
                //token = JWT.Encode(payload, new ECDsaOpenSsl(eCCurve), JwsAlgorithm.ES256);
                //Program.VerifyResult("JwsAlgorithm.ES256: ", token, new ECDsaOpenSsl(eCCurve));
            }

            privateX509Path = @"SHA256ECDSA.pfx";
            publicX509Path  = @"SHA256ECDSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test");
            publicX509Key   = new X509Certificate2(publicX509Path, "");

            try
            {
                if (os.Platform == PlatformID.Unix)
                {
                    // ECCurveを分析してみる。
                    ECCurve eCCurve = ((ECDsaOpenSsl)privateX509Key.GetECDsaPrivateKey()).ExportExplicitParameters(true).Curve;
                    Program.MyWriteLine("Inspect ECCurve: " + ObjectInspector.Inspect(eCCurve));
                }

                token = "";
                token = JWT.Encode(payload, privateX509Key.GetECDsaPrivateKey(), JwsAlgorithm.ES256);
                Program.VerifyResult("JwsAlgorithm.ES256: ", token, publicX509Key.GetECDsaPublicKey());
            }
            catch (Exception ex)
            {
                Program.MyWriteLine("JwsAlgorithm.ES256: " + ex.GetType().ToString() + ", " + ex.Message);
            }

            #endregion

            #endregion

            #region JWE (Creating encrypted Tokens)
            // https://github.com/dvsekhvalnov/jose-jwt#creating-encrypted-tokens

            #region RSA-* key management family of algorithms
            // RSA-OAEP-256, RSA-OAEP and RSA1_5 key
            // https://github.com/dvsekhvalnov/jose-jwt#rsa--key-management-family-of-algorithms

            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);

            // RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
            token = "";
            token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256);
            Program.VerifyResult("JweAlgorithm.RSA1_5, JweEncryption.A128CBC_HS256: ", token, privateX509Key.PrivateKey);

            // RSAES-OAEP and AES GCM
            try
            {
                token = "";
                token = JWT.Encode(payload, publicX509Key.PublicKey.Key, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
                Program.VerifyResult("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM: ", token, privateX509Key.PrivateKey);
            }
            catch (Exception ex)
            {
                // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                Program.MyWriteLine("JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM: " + ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region Other key management family of algorithms

            secretKey = new byte[] { 164, 60, 194, 0, 161, 189, 41, 38, 130, 89, 141, 164, 45, 170, 159, 209, 69, 137, 243, 216, 191, 131, 47, 250, 32, 107, 231, 117, 37, 158, 225, 234 };

            #region DIR direct pre-shared symmetric key family of algorithms
            // https://github.com/dvsekhvalnov/jose-jwt#dir-direct-pre-shared-symmetric-key-family-of-algorithms
            token = "";
            token = JWT.Encode(payload, secretKey, JweAlgorithm.DIR, JweEncryption.A128CBC_HS256);
            Program.VerifyResult("JweAlgorithm.DIR, JweEncryption.A128CBC_HS256: ", token, secretKey);
            #endregion

            #region AES Key Wrap key management family of algorithms
            // AES128KW, AES192KW and AES256KW key management
            // https://github.com/dvsekhvalnov/jose-jwt#aes-key-wrap-key-management-family-of-algorithms
            token = "";
            token = JWT.Encode(payload, secretKey, JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512);
            Program.VerifyResult("JweAlgorithm.A256KW, JweEncryption.A256CBC_HS512: ", token, secretKey);
            #endregion

            #region AES GCM Key Wrap key management family of algorithms
            // AES128GCMKW, AES192GCMKW and AES256GCMKW key management
            // https://github.com/dvsekhvalnov/jose-jwt#aes-gcm-key-wrap-key-management-family-of-algorithms
            try
            {
                token = "";
                token = JWT.Encode(payload, secretKey, JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512);
                Program.VerifyResult("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512: ", token, secretKey);
            }
            catch (Exception ex)
            {
                // Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll' at ubunntu
                Program.MyWriteLine("JweAlgorithm.A256GCMKW, JweEncryption.A256CBC_HS512: " + ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region ECDH-ES and ECDH-ES with AES Key Wrap key management family of algorithms
            // ECDH-ES and ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW key management
            // https://github.com/dvsekhvalnov/jose-jwt#ecdh-es-and-ecdh-es-with-aes-key-wrap-key-management-family-of-algorithms
            try
            {
                x = new byte[] { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
                y = new byte[] { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
                publicKeyOfCng = EccKey.New(x, y, usage: CngKeyUsages.KeyAgreement);
                token          = "";
                token          = JWT.Encode(payload, publicKeyOfCng, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
                Program.VerifyResult("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM: ", token, publicKeyOfCng);
            }
            catch (Exception ex)
            {
                // System.NotImplementedException: 'not yet'
                Program.MyWriteLine("JweAlgorithm.ECDH_ES, JweEncryption.A256GCM: " + ex.GetType().ToString() + ", " + ex.Message);
            }
            #endregion

            #region PBES2 using HMAC SHA with AES Key Wrap key management family of algorithms
            token = "";
            token = JWT.Encode(payload, "top secret", JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512);
            Program.VerifyResult("JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512: ", token, "top secret");
            #endregion

            #endregion

            #endregion

            #endregion

            Program.MyWriteLine("----------------------------------------------------------------------------------------------------");

            #region ELSE

            #region Additional utilities
            // https://github.com/dvsekhvalnov/jose-jwt#additional-utilities

            #region Adding extra headers
            // https://github.com/dvsekhvalnov/jose-jwt#adding-extra-headers

            headers = new Dictionary <string, object>()
            {
                { "typ", "JWT" },
                { "cty", "JWT" },
                { "keyid", "111-222-333" }
            };

            privateX509Path = @"SHA256RSA.pfx";
            publicX509Path  = @"SHA256RSA.cer";
            privateX509Key  = new X509Certificate2(privateX509Path, "test", x509KS);
            publicX509Key   = new X509Certificate2(publicX509Path, "", x509KS);

            token = "";
            token = JWT.Encode(payload, privateX509Key.PrivateKey, JwsAlgorithm.RS256, extraHeaders: headers);
            Program.VerifyResult("Adding extra headers to RS256: ", token, privateX509Key.PrivateKey);
            #endregion

            #region Strict validation
            // https://github.com/dvsekhvalnov/jose-jwt#strict-validation
            // 厳密な検証では、Algorithmを指定可能
            Program.MyWriteLine("Strict validation(RS256): " + JWT.Decode(token, privateX509Key.PrivateKey, JwsAlgorithm.RS256));
            #endregion

            #region Two-phase validation
            // https://github.com/dvsekhvalnov/jose-jwt#two-phase-validation
            // ヘッダのkeyidクレームからキーを取り出して復号化する方法。
            //headers = JWT.Headers(token);
            // ・・・
            //string hoge = JWT.Decode(token, "key");
            #endregion

            #region Working with binary payload
            // https://github.com/dvsekhvalnov/jose-jwt#working-with-binary-payload
            #endregion

            #endregion

            #region Settings
            // https://github.com/dvsekhvalnov/jose-jwt#settings
            // グローバル設定

            #region Example of JWTSettings
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-jwtsettings

            #endregion

            #region Customizing json <-> object parsing & mapping
            // https://github.com/dvsekhvalnov/jose-jwt#customizing-json---object-parsing--mapping
            // マッピング
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-newtonsoftjson-mapper
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-servicestack-mapper

            #endregion

            #region Customizing algorithm implementations
            // https://github.com/dvsekhvalnov/jose-jwt#customizing-algorithm-implementations
            // https://github.com/dvsekhvalnov/jose-jwt#example-of-custom-algorithm-implementation
            #endregion

            #region Providing aliases
            // https://github.com/dvsekhvalnov/jose-jwt#providing-aliases
            #endregion

            #endregion

            #region Dealing with keys
            // https://github.com/dvsekhvalnov/jose-jwt#dealing-with-keys
            // https://github.com/dvsekhvalnov/jose-jwt#rsacryptoserviceprovider
            // - http://stackoverflow.com/questions/7444586/how-can-i-sign-a-file-using-rsa-and-sha256-with-net
            // - http://hintdesk.com/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/
            // https://github.com/dvsekhvalnov/jose-jwt#if-you-have-only-rsa-private-key
            // - http://www.donaldsbaconbytes.com/2016/08/create-jwt-with-a-private-rsa-key/
            #endregion

            #region Strong-Named assembly
            // https://github.com/dvsekhvalnov/jose-jwt#strong-named-assembly
            // - https://github.com/dvsekhvalnov/jose-jwt/issues/5
            // - https://github.com/brutaldev/StrongNameSigner
            #endregion

            #region More examples
            // https://github.com/dvsekhvalnov/jose-jwt#more-examples
            // https://github.com/dvsekhvalnov/jose-jwt/blob/master/UnitTests/TestSuite.cs
            #endregion

            #endregion

            Console.ReadKey();
        }
Exemple #20
0
        public static string JwtHs256Encode(object payload, string secret)
        {
            var secbyte = Encoding.UTF8.GetBytes(secret);

            return(JWT.Encode(payload, secbyte, JwsAlgorithm.HS256));
        }
Exemple #21
0
 public UserService(UserManager <ApplicationUser> userManager, RoleManager <IdentityRole> roleManager, IOptions <JWT> jwt)
 {
     _userManager = userManager;
     _roleManager = roleManager;
     _jwt         = jwt.Value;
 }
Exemple #22
0
        public static byte[] EncodeSkinJwt(CngKey newKey)
        {
            byte[] t  = ImportECDsaCngKeyFromCngKey(newKey.Export(CngKeyBlobFormat.EccPrivateBlob));
            CngKey tk = CngKey.Import(t, CngKeyBlobFormat.EccPrivateBlob);

            ECDiffieHellmanCng ecKey = new ECDiffieHellmanCng(newKey);

            ecKey.HashAlgorithm         = CngAlgorithm.Sha256;
            ecKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;

            var b64Key = Base64Url.Encode(ecKey.PublicKey.GetDerEncoded());

            Skin skin = new Skin
            {
                Slim     = false,
                SkinData = Encoding.Default.GetBytes(new string('Z', 8192)),
                SkinId   = "Standard_Custom"
            };

            string skin64 = Convert.ToBase64String(skin.SkinData);


            //{
            //	"ADRole": 2,
            //	"ClientRandomId": 4670680294016914277,
            //	"CurrentInputMode": 2,
            //	"DefaultInputMode": 2,
            //	"DeviceModel": "SAMSUNG GT-P5210",
            //	"DeviceOS": 1,
            //	"GameVersion": "1.1.0.4",
            //	"GuiScale": 0,
            //	"LanguageCode": "en_US",
            //	"ServerAddress": "yodamine.com:19132",
            //	"SkinData": "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79m9/+zUuP/v2r//8t/I//Ldwv/y3cL/7NS4/+zUuP/v2r//7NS4//LfyP/y3cL/8t3C/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkQSz/ZEEs/2RBLP9kQSz/KCgo/ygoKP8oKCj/KCgo/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6J1M/3q1d/96r3f/2LqU/+vTs//YupT/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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",
            //	"SkinId": "Standard_Alex",
            //	"TenantId": "",
            //	"UIProfile": 1
            //}

            string skinData = $@"
{{
	""ADRole"": 0,
	""ClientRandomId"": {new Random().Next()},
	""CurrentInputMode"": 1,
	""DefaultInputMode"": 1,
	""DeviceModel"": ""MINET CLIENT"",
	""DeviceOS"": 7,
	""GameVersion"": ""1.2.0.15"",
	""GuiScale"": 0,
	""LanguageCode"": ""en_US"",
	""ServerAddress"": ""yodamine.com:19132"",
	""SkinData"": ""{skin64}"",
	""SkinId"": ""{skin.SkinId}"",
	""TenantId"": ""75a3f792-a259-4428-9a8d-4e832fb960e4"",
	""UIProfile"": 0
}}";

            string val = JWT.Encode(skinData, tk, JwsAlgorithm.ES384, new Dictionary <string, object> {
                { "x5u", b64Key }
            });

            return(Encoding.UTF8.GetBytes(val));
        }
Exemple #23
0
        protected void DecodeCert(McpeLogin message)
        {
            byte[] buffer = message.payload;

            if (message.payload.Length != buffer.Length)
            {
                Log.Debug($"Wrong lenght {message.payload.Length} != {message.payload.Length}");
                throw new Exception($"Wrong lenght {message.payload.Length} != {message.payload.Length}");
            }

            if (Log.IsDebugEnabled)
            {
                Log.Debug("Lenght: " + message.payload.Length + ", Message: " + Convert.ToBase64String(buffer));
            }

            string certificateChain;
            string skinData;

            try
            {
                var destination = new MemoryStream(buffer);
                destination.Position = 0;
                NbtBinaryReader reader = new NbtBinaryReader(destination, false);

                var countCertData = reader.ReadInt32();
                certificateChain = Encoding.UTF8.GetString(reader.ReadBytes(countCertData));
                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Certificate Chain (Lenght={countCertData})\n{certificateChain}");
                }

                var countSkinData = reader.ReadInt32();
                skinData = Encoding.UTF8.GetString(reader.ReadBytes(countSkinData));
                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Skin data (Lenght={countSkinData})\n{skinData}");
                }
            }
            catch (Exception e)
            {
                Log.Error("Parsing login", e);
                return;
            }

            try
            {
                {
                    IDictionary <string, dynamic> headers = JWT.Headers(skinData);
                    dynamic payload = JObject.Parse(JWT.Payload(skinData));

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Skin JWT Header: {string.Join(";", headers)}");
                    }
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Skin JWT Payload:\n{payload.ToString()}");
                    }

                    // Skin JWT Payload:

                    //{
                    //  "ADRole": 2,
                    //	"ClientRandomId": 1423700530444426768,
                    //	"CurrentInputMode": 1,
                    //	"DefaultInputMode": 1,
                    //	"DeviceModel": "ASUSTeK COMPUTER INC. N550JK",
                    //	"DeviceOS": 7,
                    //	"GameVersion": "1.1.0",
                    //	"GuiScale": 0,
                    //	"LanguageCode": "en_US",
                    //	"ServerAddress": "192.168.0.3:19132",
                    //	"SkinData": "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",
                    //	"SkinId": "Standard_Custom",
                    //	"TenantId": "",
                    //	"UIProfile": 0
                    //}

                    try
                    {
                        _playerInfo.ADRole           = payload.ADRole;
                        _playerInfo.ClientId         = payload.ClientRandomId;
                        _playerInfo.CurrentInputMode = payload.CurrentInputMode;
                        _playerInfo.DefaultInputMode = payload.DefaultInputMode;
                        _playerInfo.DeviceModel      = payload.DeviceModel;
                        _playerInfo.DeviceOS         = payload.DeviceOS;
                        _playerInfo.GameVersion      = payload.GameVersion;
                        _playerInfo.GuiScale         = payload.GuiScale;
                        _playerInfo.LanguageCode     = payload.LanguageCode;
                        _playerInfo.ServerAddress    = payload.ServerAddress;
                        _playerInfo.UIProfile        = payload.UIProfile;

                        _playerInfo.Skin = new Skin()
                        {
                            SkinType = payload.SkinId,
                            Texture  = Convert.FromBase64String((string)payload.SkinData),
                        };
                    }
                    catch (Exception e)
                    {
                        Log.Error("Parsing skin data", e);
                    }
                }

                {
                    dynamic json = JObject.Parse(certificateChain);

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Certificate JSON:\n{json}");
                    }

                    JArray chain = json.chain;
                    //var chainArray = chain.ToArray();

                    string validationKey     = null;
                    string identityPublicKey = null;

                    foreach (JToken token in chain)
                    {
                        IDictionary <string, dynamic> headers = JWT.Headers(token.ToString());

                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug("Raw chain element:\n" + token.ToString());
                            Log.Debug($"JWT Header: {string.Join(";", headers)}");

                            dynamic jsonPayload = JObject.Parse(JWT.Payload(token.ToString()));
                            Log.Debug($"JWT Payload:\n{jsonPayload}");
                        }

                        // Mojang root x5u cert (string): MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V

                        if (!headers.ContainsKey("x5u"))
                        {
                            continue;
                        }

                        string x5u = headers["x5u"];

                        if (identityPublicKey == null)
                        {
                            if (CertificateData.MojangRootKey.Equals(x5u, StringComparison.InvariantCultureIgnoreCase))
                            {
                                Log.Debug("Key is ok, and got Mojang root");
                            }
                            else if (chain.Count > 1)
                            {
                                Log.Debug("Got client cert (client root)");
                                continue;
                            }
                            else if (chain.Count == 1)
                            {
                                Log.Debug("Selfsigned chain");
                            }
                        }
                        else if (identityPublicKey.Equals(x5u))
                        {
                            Log.Debug("Derived Key is ok");
                        }

                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"x5u cert (string): {x5u}");
                            ECDiffieHellmanPublicKey publicKey = CryptoUtils.CreateEcDiffieHellmanPublicKey(x5u);
                            Log.Debug($"Cert:\n{publicKey.ToXmlString()}");
                        }

                        // Validate
                        CngKey          newKey = CryptoUtils.ImportECDsaCngKeyFromString(x5u);
                        CertificateData data   = JWT.Decode <CertificateData>(token.ToString(), newKey);

                        if (data != null)
                        {
                            identityPublicKey = data.IdentityPublicKey;

                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug("Decoded token success");
                            }

                            if (CertificateData.MojangRootKey.Equals(x5u, StringComparison.InvariantCultureIgnoreCase))
                            {
                                Log.Debug("Got Mojang key. Is valid = " + data.CertificateAuthority);
                                validationKey = data.IdentityPublicKey;
                            }
                            else if (validationKey != null && validationKey.Equals(x5u, StringComparison.InvariantCultureIgnoreCase))
                            {
                                _playerInfo.CertificateData = data;
                            }
                            else
                            {
                                if (data.ExtraData == null)
                                {
                                    continue;
                                }

                                // Self signed, make sure they don't fake XUID
                                if (data.ExtraData.Xuid != null)
                                {
                                    Log.Warn("Received fake XUID from " + data.ExtraData.DisplayName);
                                    data.ExtraData.Xuid = null;
                                }

                                _playerInfo.CertificateData = data;
                            }
                        }
                        else
                        {
                            Log.Error("Not a valid Identity Public Key for decoding");
                        }
                    }

                    //TODO: Implement disconnect here

                    {
                        _playerInfo.Username = _playerInfo.CertificateData.ExtraData.DisplayName;
                        _session.Username    = _playerInfo.Username;
                        string identity = _playerInfo.CertificateData.ExtraData.Identity;

                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Connecting user {_playerInfo.Username} with identity={identity}");
                        }
                        _playerInfo.ClientUuid = new UUID(identity);

                        _session.CryptoContext = new CryptoContext
                        {
                            UseEncryption = Config.GetProperty("UseEncryptionForAll", false) || (Config.GetProperty("UseEncryption", true) && !string.IsNullOrWhiteSpace(_playerInfo.CertificateData.ExtraData.Xuid)),
                        };

                        if (_session.CryptoContext.UseEncryption)
                        {
                            ECDiffieHellmanPublicKey publicKey = CryptoUtils.CreateEcDiffieHellmanPublicKey(_playerInfo.CertificateData.IdentityPublicKey);
                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug($"Cert:\n{publicKey.ToXmlString()}");
                            }

                            // Create shared shared secret
                            ECDiffieHellmanCng ecKey = new ECDiffieHellmanCng(384);
                            ecKey.HashAlgorithm         = CngAlgorithm.Sha256;
                            ecKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                            ecKey.SecretPrepend         = Encoding.UTF8.GetBytes("RANDOM SECRET");                     // Server token

                            byte[] secret = ecKey.DeriveKeyMaterial(publicKey);

                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug($"SECRET KEY (b64):\n{Convert.ToBase64String(secret)}");
                            }

                            {
                                RijndaelManaged rijAlg = new RijndaelManaged
                                {
                                    BlockSize    = 128,
                                    Padding      = PaddingMode.None,
                                    Mode         = CipherMode.CFB,
                                    FeedbackSize = 8,
                                    Key          = secret,
                                    IV           = secret.Take(16).ToArray(),
                                };

                                // Create a decrytor to perform the stream transform.
                                ICryptoTransform decryptor      = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
                                MemoryStream     inputStream    = new MemoryStream();
                                CryptoStream     cryptoStreamIn = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read);

                                ICryptoTransform encryptor       = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
                                MemoryStream     outputStream    = new MemoryStream();
                                CryptoStream     cryptoStreamOut = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write);

                                _session.CryptoContext.Algorithm       = rijAlg;
                                _session.CryptoContext.Decryptor       = decryptor;
                                _session.CryptoContext.Encryptor       = encryptor;
                                _session.CryptoContext.InputStream     = inputStream;
                                _session.CryptoContext.OutputStream    = outputStream;
                                _session.CryptoContext.CryptoStreamIn  = cryptoStreamIn;
                                _session.CryptoContext.CryptoStreamOut = cryptoStreamOut;
                            }

                            var response = McpeServerToClientHandshake.CreateObject();
                            response.NoBatch         = true;
                            response.ForceClear      = true;
                            response.serverPublicKey = Convert.ToBase64String(ecKey.PublicKey.GetDerEncoded());
                            response.tokenLength     = (short)ecKey.SecretPrepend.Length;
                            response.token           = ecKey.SecretPrepend;

                            _session.SendPackage(response);

                            if (Log.IsDebugEnabled)
                            {
                                Log.Warn($"Encryption enabled for {_session.Username}");
                            }
                        }
                    }
                }

                if (!_session.CryptoContext.UseEncryption)
                {
                    _session.MessageHandler.HandleMcpeClientToServerHandshake(null);
                }
            }
            catch (Exception e)
            {
                Log.Error("Decrypt", e);
            }
        }
Exemple #24
0
        /// <summary>
        /// Unpacks a JWT token into raw JSON.
        /// </summary>
        /// <param name="token">The JWT toekn.</param>
        /// <param name="secretKey">The decryption key. Leave null if unencrypted.</param>
        /// <returns>The raw JSON of the original key-value pairs.</returns>
        public static string Unpack(string token, string secretKey = null)
        {
            string json = JWT.Decode(token, secretKey);

            return(json);
        }
Exemple #25
0
 public auth(UserManager <users> user, IOptions <JWT> jwt, RoleManager <IdentityRole> role)
 {
     _jwt  = jwt.Value;
     _user = user;
     _role = role;
 }
Exemple #26
0
        public void TestJWTHandling()
        {
            CngKey newKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP384, null, new CngKeyCreationParameters()
            {
                ExportPolicy = CngExportPolicies.AllowPlaintextExport, KeyUsage = CngKeyUsages.AllUsages
            });

            byte[] t  = CryptoUtils.ImportECDsaCngKeyFromCngKey(newKey.Export(CngKeyBlobFormat.EccPrivateBlob));
            CngKey tk = CngKey.Import(t, CngKeyBlobFormat.EccPrivateBlob);

            Assert.AreEqual(CngAlgorithmGroup.ECDsa, tk.AlgorithmGroup);

            ECDiffieHellmanCng ecKey = new ECDiffieHellmanCng(newKey);

            ecKey.HashAlgorithm         = CngAlgorithm.Sha256;
            ecKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;

            var             b64Key          = Base64Url.Encode(ecKey.PublicKey.GetDerEncoded());
            string          test            = $@"
{{ 
	""exp"": 1464983845, 
	""extraData"": {{ 
		""displayName"": ""gurunx"",	
		""identity"": ""af6f7c5e -fcea-3e43-bf3a-e005e400e578""	
	}},	
	""identityPublicKey"": ""{b64Key}"",
	""nbf"": 1464983844
}}";
            CertificateData certificateData = new CertificateData
            {
                Exp       = 1464983845,
                ExtraData = new ExtraData
                {
                    DisplayName = "gurun",
                    Identity    = "af6f7c5e -fcea-3e43-bf3a-e005e400e578",
                },
                IdentityPublicKey = b64Key,
                Nbf = 1464983844,
            };

            JWT.JsonMapper = new NewtonsoftMapper();

            string val = JWT.Encode(certificateData, tk, JwsAlgorithm.ES384, new Dictionary <string, object> {
                { "x5u", b64Key }
            });

            Console.WriteLine(val);

            Assert.AreEqual(b64Key, JWT.Headers(val)["x5u"]);
            //Assert.AreEqual("", string.Join(";", JWT.Headers(val)));
            //Assert.AreEqual(test, JWT.Payload(val));

            Console.WriteLine(JWT.Payload(val));


            IDictionary <string, dynamic> headers = JWT.Headers(val);

            if (headers.ContainsKey("x5u"))
            {
                string certString = headers["x5u"];

                // Validate
                CngKey          importKey = CryptoUtils.ImportECDsaCngKeyFromString(certString);
                CertificateData data      = JWT.Decode <CertificateData>(val, importKey);
                Assert.NotNull(data);
                Assert.AreEqual(certificateData.Exp, data.Exp);
                Assert.AreEqual(certificateData.IdentityPublicKey, data.IdentityPublicKey);
                Assert.AreEqual(certificateData.Nbf, data.Nbf);
                Assert.NotNull(data.ExtraData);
                Assert.AreEqual(certificateData.ExtraData.DisplayName, data.ExtraData.DisplayName);
                Assert.AreEqual(certificateData.ExtraData.Identity, data.ExtraData.Identity);
            }
        }
Exemple #27
0
 public static Dictionary <string, object> GetToken(string token)
 {
     return(JWT.Decode <Dictionary <string, object> >(token, Encoding.UTF8.GetBytes(Key), JwsAlgorithm.HS512));
 }
        public void GetTokenAsync_OnCredentials_ReturnsAuthenticationModel()
        {
            var claims = new List <Claim>()
            {
                new Claim("roles", "test")
            } as IList <Claim>;

            var roles = new List <string>()
            {
                "User"
            } as IList <string>;

            var applicationUser = new ApplicationUser
            {
                Id       = Guid.NewGuid().ToString(),
                Email    = "*****@*****.**",
                UserName = "******"
            };

            var jwt = new JWT
            {
                Audience          = "test",
                DurationInMinutes = 50,
                Issuer            = "test",
                Key = "some_big_key_value_here_secret_123"
            };

            var userManagerWrapperMock = new Mock <IUserManagerWrapper>();
            var jwtTokenMock           = new Mock <IOptions <JWT> >();

            jwtTokenMock.Setup(x => x.Value)
            .Returns(jwt);
            userManagerWrapperMock
            .Setup(x => x.FindByEmailAsync(It.IsAny <string>()))
            .Returns(Task.FromResult(applicationUser));
            userManagerWrapperMock
            .Setup(x => x.CheckPasswordAsync(It.IsAny <ApplicationUser>(), It.IsAny <string>()))
            .Returns(Task.FromResult(true));
            userManagerWrapperMock
            .Setup(x => x.GetClaimsAsync(It.IsAny <ApplicationUser>()))
            .Returns(Task.FromResult(claims));
            userManagerWrapperMock
            .Setup(x => x.GetRolesAsync(It.IsAny <ApplicationUser>()))
            .Returns(Task.FromResult(roles));

            var sut = new UserService(userManagerWrapperMock.Object, jwtTokenMock.Object);

            var getTokenQuery = new GetTokenQuery
            {
                Email    = "*****@*****.**",
                Password = "******"
            };

            var result = sut.GetTokenAsync(getTokenQuery).GetAwaiter().GetResult();


            result.Should().NotBeNull();
            result.Email.Should().Be("*****@*****.**");
            result.IsAuthenticated.Should().Be(true);
            result.UserName.Should().Be("*****@*****.**");
        }
Exemple #29
0
        public static int GetTokenPermission(string token)
        {
            var tokenData = JWT.Decode <Dictionary <string, object> >(token, Encoding.UTF8.GetBytes(Key), JwsAlgorithm.HS512);

            return((int)tokenData["Permission"]);
        }
Exemple #30
0
        public static string GetTokenRole(string cookie)
        {
            var decodedToken = JWT.Decode <JWT.Container <LoginToken> >(cookie);

            return(decodedToken.Data.Role);
        }
        /// <summary>
        /// RSAES with SHA-256 using Optimal Asymmetric Jwe Padding, RFC 3447
        /// AES GCM Key Wrap Algorithm using 256 bit keys
        /// </summary>
        /// <param name="rsa"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static string Decrypt(RSA rsa, string token)
        {
            var plain = JWT.Decode(token, rsa, JweAlgorithm.RSA_OAEP_256, JweEncryption.A256GCM);

            return(plain);
        }