Beispiel #1
0
 public static byte[] Decrypt(byte[] encryptedBytes, byte[] cryptKey, byte[] iv)
 {
     using (var aes = CreateSymmetricAlgorithm())
         using (var decryptor = aes.CreateDecryptor(cryptKey, iv))
             using (var ms = MemoryStreamFactory.GetStream(encryptedBytes))
                 using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                 {
                     return(cryptStream.ReadFully());
                 }
 }
Beispiel #2
0
        public static byte[] Decrypt(byte[] encryptedBytes, byte[] aesKey, byte[] iv)
        {
            using (SymmetricAlgorithm aes = new AesCryptoServiceProvider())
            {
                aes.KeySize = KeySize;
                aes.Key     = aesKey;
                aes.IV      = iv;

                using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
                    using (var ms = MemoryStreamFactory.GetStream(encryptedBytes))
                        using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                        {
                            return(cryptStream.ReadFully());
                        }
            }
        }
Beispiel #3
0
        public byte[] ProcessBlock(byte[] cipherText)
        {
            var plainText      = new byte[CRYPTO_BLOCK_SIZE];
            var decryptedBytes = new List <byte>();
            var decryptor      = rijndael.CreateDecryptor();

            using (var msDecrypt = new MemoryStream(cipherText))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    csDecrypt.ReadFully(plainText);
                }
            }

            for (int j = 0; j < plainText.Length; j++)
            {
                decryptedBytes.Add((byte)(plainText[j] ^ aesInitializationVector[j % 16])); //32:114, 33:101
            }
            for (int j = 0; j < aesInitializationVector.Length; j++)
            {
                aesInitializationVector[j] = cipherText[j];
            }
            return(decryptedBytes.ToArray());
        }
Beispiel #4
0
        public void PreAuthenticate(IRequest req, IResponse res)
        {
            if (req.OperationName != null && IgnoreForOperationTypes.Contains(req.OperationName))
            {
                return;
            }

            var bearerToken = req.GetBearerToken()
                              ?? req.GetCookieValue(Keywords.TokenCookie);

            if (bearerToken != null)
            {
                var parts = bearerToken.Split('.');
                if (parts.Length == 3)
                {
                    if (RequireSecureConnection && !req.IsSecureConnection)
                    {
                        throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection);
                    }

                    var header         = parts[0];
                    var payload        = parts[1];
                    var signatureBytes = parts[2].FromBase64UrlSafe();

                    var headerJson   = header.FromBase64UrlSafe().FromUtf8Bytes();
                    var payloadBytes = payload.FromBase64UrlSafe();

                    var headerData = headerJson.FromJson <Dictionary <string, string> >();

                    var bytesToSign = string.Concat(header, ".", payload).ToUtf8Bytes();

                    var algorithm = headerData["alg"];

                    //Potential Security Risk for relying on user-specified algorithm: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
                    if (RequireHashAlgorithm && algorithm != HashAlgorithm)
                    {
                        throw new NotSupportedException("Invalid algoritm '{0}', expected '{1}'".Fmt(algorithm, HashAlgorithm));
                    }

                    if (!VerifyPayload(algorithm, bytesToSign, signatureBytes))
                    {
                        return;
                    }

                    var payloadJson = payloadBytes.FromUtf8Bytes();
                    var jwtPayload  = JsonObject.Parse(payloadJson);

                    var session = CreateSessionFromPayload(req, jwtPayload);
                    req.Items[Keywords.Session] = session;
                }
                else if (parts.Length == 5) //Encrypted JWE Token
                {
                    if (RequireSecureConnection && !req.IsSecureConnection)
                    {
                        throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection);
                    }

                    if (PrivateKey == null || PublicKey == null)
                    {
                        throw new NotSupportedException("PrivateKey is required to DecryptPayload");
                    }

                    var jweHeaderBase64Url  = parts[0];
                    var jweEncKeyBase64Url  = parts[1];
                    var ivBase64Url         = parts[2];
                    var cipherTextBase64Url = parts[3];
                    var tagBase64Url        = parts[4];

                    var sentTag    = tagBase64Url.FromBase64UrlSafe();
                    var aadBytes   = (jweHeaderBase64Url + "." + jweEncKeyBase64Url).ToUtf8Bytes();
                    var iv         = ivBase64Url.FromBase64UrlSafe();
                    var cipherText = cipherTextBase64Url.FromBase64UrlSafe();

                    var jweEncKey        = jweEncKeyBase64Url.FromBase64UrlSafe();
                    var cryptAuthKeys256 = RsaUtils.Decrypt(jweEncKey, PrivateKey.Value, UseRsaKeyLength);

                    var authKey  = new byte[128 / 8];
                    var cryptKey = new byte[128 / 8];
                    Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length);
                    Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length);

                    using (var hmac = new HMACSHA256(authKey))
                        using (var encryptedStream = new MemoryStream())
                        {
                            using (var writer = new BinaryWriter(encryptedStream))
                            {
                                writer.Write(aadBytes);
                                writer.Write(iv);
                                writer.Write(cipherText);
                                writer.Flush();

                                var calcTag = hmac.ComputeHash(encryptedStream.ToArray());

                                if (!calcTag.EquivalentTo(sentTag))
                                {
                                    return;
                                }
                            }
                        }

                    JsonObject jwtPayload;
                    var        aes = Aes.Create();
                    aes.KeySize   = 128;
                    aes.BlockSize = 128;
                    aes.Mode      = CipherMode.CBC;
                    aes.Padding   = PaddingMode.PKCS7;
                    using (aes)
                        using (var decryptor = aes.CreateDecryptor(cryptKey, iv))
                            using (var ms = MemoryStreamFactory.GetStream(cipherText))
                                using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                                {
                                    var jwtPayloadBytes = cryptStream.ReadFully();
                                    jwtPayload = JsonObject.Parse(jwtPayloadBytes.FromUtf8Bytes());
                                }

                    var session = CreateSessionFromPayload(req, jwtPayload);
                    req.Items[Keywords.Session] = session;
                }
            }
        }
        public void PreAuthenticate(IRequest req, IResponse res)
        {
            if (req.OperationName != null && IgnoreForOperationTypes.Contains(req.OperationName))
            {
                return;
            }

            var bearerToken = req.GetJwtToken();

            if (bearerToken != null)
            {
                var parts = bearerToken.Split('.');
                if (parts.Length == 3)
                {
                    if (RequireSecureConnection && !req.IsSecureConnection)
                    {
                        throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection);
                    }

                    var jwtPayload = GetVerifiedJwtPayload(parts);
                    if (jwtPayload == null) //not verified
                    {
                        return;
                    }

                    if (ValidateToken != null)
                    {
                        if (!ValidateToken(jwtPayload, req))
                        {
                            throw HttpError.Forbidden(ErrorMessages.TokenInvalid);
                        }
                    }

                    var session = CreateSessionFromPayload(req, jwtPayload);
                    req.Items[Keywords.Session] = session;
                }
                else if (parts.Length == 5) //Encrypted JWE Token
                {
                    if (RequireSecureConnection && !req.IsSecureConnection)
                    {
                        throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection);
                    }

                    if (PrivateKey == null || PublicKey == null)
                    {
                        throw new NotSupportedException("PrivateKey is required to DecryptPayload");
                    }

                    var jweHeaderBase64Url  = parts[0];
                    var jweEncKeyBase64Url  = parts[1];
                    var ivBase64Url         = parts[2];
                    var cipherTextBase64Url = parts[3];
                    var tagBase64Url        = parts[4];

                    var sentTag    = tagBase64Url.FromBase64UrlSafe();
                    var aadBytes   = (jweHeaderBase64Url + "." + jweEncKeyBase64Url).ToUtf8Bytes();
                    var iv         = ivBase64Url.FromBase64UrlSafe();
                    var cipherText = cipherTextBase64Url.FromBase64UrlSafe();

                    var jweEncKey        = jweEncKeyBase64Url.FromBase64UrlSafe();
                    var cryptAuthKeys256 = RsaUtils.Decrypt(jweEncKey, PrivateKey.Value, UseRsaKeyLength);

                    var authKey  = new byte[128 / 8];
                    var cryptKey = new byte[128 / 8];
                    Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length);
                    Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length);

                    using (var hmac = new HMACSHA256(authKey))
                        using (var encryptedStream = new MemoryStream())
                        {
                            using (var writer = new BinaryWriter(encryptedStream))
                            {
                                writer.Write(aadBytes);
                                writer.Write(iv);
                                writer.Write(cipherText);
                                writer.Flush();

                                var calcTag = hmac.ComputeHash(encryptedStream.ToArray());

                                if (!calcTag.EquivalentTo(sentTag))
                                {
                                    return;
                                }
                            }
                        }

                    JsonObject jwtPayload;
                    var        aes = Aes.Create();
                    aes.KeySize   = 128;
                    aes.BlockSize = 128;
                    aes.Mode      = CipherMode.CBC;
                    aes.Padding   = PaddingMode.PKCS7;
                    using (aes)
                        using (var decryptor = aes.CreateDecryptor(cryptKey, iv))
                            using (var ms = MemoryStreamFactory.GetStream(cipherText))
                                using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                                {
                                    var jwtPayloadBytes = cryptStream.ReadFully();
                                    jwtPayload = JsonObject.Parse(jwtPayloadBytes.FromUtf8Bytes());
                                }

                    if (ValidateToken != null)
                    {
                        if (!ValidateToken(jwtPayload, req))
                        {
                            throw HttpError.Forbidden(ErrorMessages.TokenInvalid);
                        }
                    }

                    var session = CreateSessionFromPayload(req, jwtPayload);
                    req.Items[Keywords.Session] = session;
                }
            }
        }
        public JsonObject GetVerifiedJwtPayload(string[] parts)
        {
            if (parts.Length == 3)
            {
                var header         = parts[0];
                var payload        = parts[1];
                var signatureBytes = parts[2].FromBase64UrlSafe();

                var headerJson   = header.FromBase64UrlSafe().FromUtf8Bytes();
                var payloadBytes = payload.FromBase64UrlSafe();

                var headerData = headerJson.FromJson <Dictionary <string, string> >();

                var bytesToSign = string.Concat(header, ".", payload).ToUtf8Bytes();

                var algorithm = headerData["alg"];

                //Potential Security Risk for relying on user-specified algorithm: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
                if (RequireHashAlgorithm && algorithm != HashAlgorithm)
                {
                    throw new NotSupportedException($"Invalid algoritm '{algorithm}', expected '{HashAlgorithm}'");
                }

                if (!VerifyPayload(algorithm, bytesToSign, signatureBytes))
                {
                    return(null);
                }

                var payloadJson = payloadBytes.FromUtf8Bytes();
                var jwtPayload  = JsonObject.Parse(payloadJson);
                return(jwtPayload);
            }
            if (parts.Length == 5) //Encrypted JWE Token
            {
                var jweHeaderBase64Url  = parts[0];
                var jweEncKeyBase64Url  = parts[1];
                var ivBase64Url         = parts[2];
                var cipherTextBase64Url = parts[3];
                var tagBase64Url        = parts[4];

                var sentTag    = tagBase64Url.FromBase64UrlSafe();
                var aadBytes   = (jweHeaderBase64Url + "." + jweEncKeyBase64Url).ToUtf8Bytes();
                var iv         = ivBase64Url.FromBase64UrlSafe();
                var cipherText = cipherTextBase64Url.FromBase64UrlSafe();

                var jweEncKey        = jweEncKeyBase64Url.FromBase64UrlSafe();
                var cryptAuthKeys256 = RsaUtils.Decrypt(jweEncKey, PrivateKey.Value, UseRsaKeyLength);

                var authKey  = new byte[128 / 8];
                var cryptKey = new byte[128 / 8];
                Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length);
                Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length);

                using (var hmac = new HMACSHA256(authKey))
                    using (var encryptedStream = new MemoryStream())
                    {
                        using (var writer = new BinaryWriter(encryptedStream))
                        {
                            writer.Write(aadBytes);
                            writer.Write(iv);
                            writer.Write(cipherText);
                            writer.Flush();

                            var calcTag = hmac.ComputeHash(encryptedStream.ToArray());

                            if (!calcTag.EquivalentTo(sentTag))
                            {
                                return(null);
                            }
                        }
                    }

                var aes = Aes.Create();
                aes.KeySize   = 128;
                aes.BlockSize = 128;
                aes.Mode      = CipherMode.CBC;
                aes.Padding   = PaddingMode.PKCS7;
                using (aes)
                    using (var decryptor = aes.CreateDecryptor(cryptKey, iv))
                        using (var ms = MemoryStreamFactory.GetStream(cipherText))
                            using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                            {
                                var jwtPayloadBytes = cryptStream.ReadFully();
                                return(JsonObject.Parse(jwtPayloadBytes.FromUtf8Bytes()));
                            }
            }

            throw new ArgumentException(ErrorMessages.TokenInvalid);
        }
Beispiel #7
0
        /// <summary>
        /// Load the specified identifier, if not exists, returns the default value.
        /// </summary>
        /// <param name="identifier">Identifier.</param>
        /// <param name="type">Type.</param>
        /// <param name="defaultValue">Default value.</param>
        /// <param name="settings">Settings.</param>
        public static object Load(string identifier, Type type, object defaultValue, SaveGameSettings settings)
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentNullException("identifier");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (defaultValue == null)
            {
                defaultValue = type.GetDefault();
            }
            settings.Identifier = identifier;
            if (!Exists(settings.Identifier, settings))
            {
                if (defaultValue == null)
                {
                    Debug.LogWarning("SaveGamePro: The specified identifier does not exists, please make sure the identifeir is exist before loading. The Default value is not specified, it might make exceptions and errors.");
                }
                else
                {
                    Debug.LogWarning("SaveGamePro: The specified identifier does not exists, please make sure the identifeir is exist before loading. Returning default value.");
                }
                return(defaultValue);
            }
            settings.Storage.OnLoad(settings);
            object result = null;
            Stream stream = settings.Storage.GetReadStream(settings);

            if (settings.Encrypt)
            {
                using (MemoryStream dataOut = new MemoryStream())
                {
                    using (MemoryStream memoryStream = new MemoryStream(stream.ReadFully()))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, settings.Decryptor, CryptoStreamMode.Read))
                        {
                            byte[] decryptedData = cryptoStream.ReadFully();
                            dataOut.Write(decryptedData, 0, decryptedData.Length);
                        }
                    }
                    dataOut.Flush();
                    result = settings.Formatter.Deserialize(dataOut, type, settings);
                }
            }
            else
            {
                result = settings.Formatter.Deserialize(stream, type, settings);
            }
            settings.Storage.OnLoaded(settings);
            stream.Dispose();
            if (result == null)
            {
                result = defaultValue;
            }
            if (OnLoaded != null)
            {
                OnLoaded(identifier, result, type, defaultValue, settings);
            }
            return(result);
        }