Exemple #1
0
        public void LoadFromProtectedString(string protectedString, RMSecureString password)
        {
            Clear();

            if (protectedString.StartsWith("e"))
            {
                LoadFromEncryptedString(protectedString, password);
            }
            else if (protectedString.StartsWith("p"))
            {
                // Trim leading 'p', which is just an indicator to say that this is an encrypted and not a protected string
                protectedString = protectedString.Substring(1);

                IntPtr PasswordPtr = IntPtr.Zero;

                try
                {
                    // Get the secure password string into a memory buffer
                    PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                    int PasswordSize = password.Length * sizeof(byte);

                    // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                    unsafe
                    {
                        byte[] Decrypted     = null;
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed(byte *ptr = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                if (PasswordSize == 0)
                                {
                                    Decrypted = ProtectedData.Unprotect(Convert.FromBase64String(protectedString), null, DataProtectionScope.CurrentUser);
                                }
                                else
                                {
                                    Decrypted = ProtectedData.Unprotect(Convert.FromBase64String(protectedString), PasswordBytes, DataProtectionScope.CurrentUser);
                                }

                                for (int i = 0; i < Decrypted.Length; i++)
                                {
                                    if (_SecureStringSupported)
                                    {
                                        ((SecureString)_SecureString).AppendChar((char)Decrypted[i]);
                                    }
                                    else
                                    {
                                        ((StringBuilder)_SecureString).Append((char)Decrypted[i]);
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                if (Decrypted != null)
                                {
                                    Array.Clear(Decrypted, 0, Decrypted.Length);
                                }
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
                finally
                {
                    // Ensure unmanaged memory is released.
                    if (PasswordPtr != IntPtr.Zero)
                    {
                        Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Encrypt the current SecureString with the ProtectData API, returning the computed value as a base64 string
        /// </summary>
        /// <returns>A base64 encoded string of the protected version of the current SecureString</returns>
        /// <remarks>Based on the code from Sly Gryphon's comment at http://weblogs.asp.net/pglavich/archive/2006/10/29/Secure-TextBox-Updated.aspx </remarks>
        public string GetProtectedString(RMSecureString password)
        {
            string Result = "";

            IntPtr PlainTextPtr = IntPtr.Zero;
            IntPtr PasswordPtr  = IntPtr.Zero;

            try
            {
                // Get the secure plaintext string into a memory buffer
                if (_SecureStringSupported)
                {
                    PlainTextPtr = Marshal.SecureStringToGlobalAllocAnsi((SecureString)_SecureString);
                }
                else
                {
                    PlainTextPtr = Marshal.StringToHGlobalAnsi(((StringBuilder)_SecureString).ToString());
                }
                int PlainTextSize = this.Length * sizeof(byte);

                // Get the secure password string into a memory buffer
                PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                int PasswordSize = password.Length * sizeof(byte);

                // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                unsafe
                {
                    byte[] PlainTextBytes = new byte[PlainTextSize];
                    fixed(byte *ptr1 = PlainTextBytes)
                    {
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed(byte *ptr2 = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PlainTextPtr, PlainTextBytes, 0, PlainTextSize);
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                if (PasswordSize == 0)
                                {
                                    Result = "p" + Convert.ToBase64String(ProtectedData.Protect(PlainTextBytes, null, DataProtectionScope.CurrentUser));
                                }
                                else
                                {
                                    Result = "p" + Convert.ToBase64String(ProtectedData.Protect(PlainTextBytes, PasswordBytes, DataProtectionScope.CurrentUser));
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                Array.Clear(PlainTextBytes, 0, PlainTextSize);

                                // Ensure managed array is cleared
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
            }
            finally
            {
                // Ensure unmanaged memory is released.
                if (PlainTextPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PlainTextPtr);
                }

                // Ensure unmanaged memory is released.
                if (PasswordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                }
            }

            return(Result);
        }
Exemple #3
0
        public void LoadFromEncryptedString(string encryptedString, RMSecureString password)
        {
            Clear();

            if (encryptedString.StartsWith("p"))
            {
                LoadFromProtectedString(encryptedString, password);
            }
            else if (encryptedString.StartsWith("e"))
            {
                // Trim leading 'e', which is just an indicator to say that this is an encrypted and not a protected string
                encryptedString = encryptedString.Substring(1);

                IntPtr PasswordPtr = IntPtr.Zero;

                try
                {
                    // Get the secure password string into a memory buffer
                    PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                    int PasswordSize = password.Length * sizeof(byte);

                    // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                    unsafe
                    {
                        byte[] Decrypted     = null;
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed(byte *ptr = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(PasswordBytes, Encoding.ASCII.GetBytes("RMSecureString"), "SHA512", 12345);
                                using (RijndaelManaged SymmetricKey = new RijndaelManaged())
                                {
                                    SymmetricKey.Mode = CipherMode.CBC;
                                    using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(DerivedPassword.GetBytes(32), DerivedPassword.GetBytes(16)))
                                    {
                                        using (MemoryStream MemStream = new MemoryStream(Convert.FromBase64String(encryptedString)))
                                        {
                                            using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read))
                                            {
                                                byte[] DecryptedByte = new byte[1];

                                                int ByteCount = CryptoStream.Read(DecryptedByte, 0, 1);
                                                while (ByteCount > 0)
                                                {
                                                    if (_SecureStringSupported)
                                                    {
                                                        ((SecureString)_SecureString).AppendChar((char)DecryptedByte[0]);
                                                    }
                                                    else
                                                    {
                                                        ((StringBuilder)_SecureString).Append((char)DecryptedByte[0]);
                                                    }
                                                    ByteCount = CryptoStream.Read(DecryptedByte, 0, 1);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                if (Decrypted != null)
                                {
                                    Array.Clear(Decrypted, 0, Decrypted.Length);
                                }
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
                finally
                {
                    // Ensure unmanaged memory is released.
                    if (PasswordPtr != IntPtr.Zero)
                    {
                        Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                    }
                }
            }
        }
Exemple #4
0
        private void LoadFromEncryptedStringv2(string encryptedString, RMSecureString password)
        {
            Clear();

            // encryptedString is in the format e!2!{iterations}!{base64:salt}!{base64:iv}!{base64:encrypted_password}, so split it
            string[] Pieces     = encryptedString.Split('!');
            int      Iterations = int.Parse(Pieces[2]);

            byte[] SaltBytes = Convert.FromBase64String(Pieces[3]);
            byte[] IVBytes   = Convert.FromBase64String(Pieces[4]);
            encryptedString = Pieces[5];

            IntPtr PasswordPtr = IntPtr.Zero;

            try {
                // Get the secure password string into a memory buffer
                PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                int PasswordSize = password.Length * sizeof(byte);

                // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                unsafe {
                    byte[] Decrypted     = null;
                    byte[] PasswordBytes = new byte[PasswordSize];
                    fixed(byte *ptr = PasswordBytes)
                    {
                        try {
                            Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                            var DerivedPassword = new Rfc2898DeriveBytes(PasswordBytes, SaltBytes, Iterations);
                            using (RijndaelManaged SymmetricKey = new RijndaelManaged()) {
                                SymmetricKey.IV   = IVBytes;
                                SymmetricKey.Key  = DerivedPassword.GetBytes(16);
                                SymmetricKey.Mode = CipherMode.CBC;
                                using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor()) {
                                    using (MemoryStream MemStream = new MemoryStream(Convert.FromBase64String(encryptedString))) {
                                        using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)) {
                                            byte[] DecryptedByte = new byte[1];

                                            int ByteCount = CryptoStream.Read(DecryptedByte, 0, 1);
                                            while (ByteCount > 0)
                                            {
                                                _SecureString.AppendChar((char)DecryptedByte[0]);
                                                ByteCount = CryptoStream.Read(DecryptedByte, 0, 1);
                                            }
                                        }
                                    }
                                }
                            }
                        } finally {
                            // Ensure managed array is cleared
                            if (Decrypted != null)
                            {
                                Array.Clear(Decrypted, 0, Decrypted.Length);
                            }
                            Array.Clear(PasswordBytes, 0, PasswordSize);
                        }
                    }
                }
            } finally {
                // Ensure unmanaged memory is released.
                if (PasswordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                }
            }
        }
Exemple #5
0
        public string GetEncryptedString(RMSecureString password)
        {
            string Result = "";

            IntPtr PlainTextPtr = IntPtr.Zero;
            IntPtr PasswordPtr  = IntPtr.Zero;

            try
            {
                // Get the secure plaintext string into a memory buffer
                if (_SecureStringSupported)
                {
                    PlainTextPtr = Marshal.SecureStringToGlobalAllocAnsi((SecureString)_SecureString);
                }
                else
                {
                    PlainTextPtr = Marshal.StringToHGlobalAnsi(((StringBuilder)_SecureString).ToString());
                }
                int PlainTextSize = this.Length * sizeof(byte);

                // Get the secure password string into a memory buffer
                PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                int PasswordSize = password.Length * sizeof(byte);

                // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                unsafe
                {
                    byte[] PlainTextBytes = new byte[PlainTextSize];
                    fixed(byte *ptr1 = PlainTextBytes)
                    {
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed(byte *ptr2 = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PlainTextPtr, PlainTextBytes, 0, PlainTextSize);
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(PasswordBytes, Encoding.ASCII.GetBytes("RMSecureString"), "SHA512", 12345);
                                using (RijndaelManaged SymmetricKey = new RijndaelManaged())
                                {
                                    SymmetricKey.Mode = CipherMode.CBC;
                                    using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(DerivedPassword.GetBytes(32), DerivedPassword.GetBytes(16)))
                                    {
                                        using (MemoryStream MemStream = new MemoryStream())
                                        {
                                            using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
                                            {
                                                CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
                                                CryptoStream.FlushFinalBlock();

                                                Result = "e" + Convert.ToBase64String(MemStream.ToArray());
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                Array.Clear(PlainTextBytes, 0, PlainTextSize);

                                // Ensure managed array is cleared
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
            }
            finally
            {
                // Ensure unmanaged memory is released.
                if (PlainTextPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PlainTextPtr);
                }

                // Ensure unmanaged memory is released.
                if (PasswordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                }
            }

            return(Result);
        }
Exemple #6
0
        public string GetEncryptedString(RMSecureString password, int iterations = 32768)
        {
            string Result = "";

            IntPtr PlainTextPtr = IntPtr.Zero;
            IntPtr PasswordPtr  = IntPtr.Zero;

            try
            {
                // Get the secure plaintext string into a memory buffer
                PlainTextPtr = Marshal.SecureStringToGlobalAllocAnsi(_SecureString);
                int PlainTextSize = this.Length * sizeof(byte);

                // Get the secure password string into a memory buffer
                PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                int PasswordSize = password.Length * sizeof(byte);

                // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                unsafe
                {
                    byte[] PlainTextBytes = new byte[PlainTextSize];
                    fixed(byte *ptr1 = PlainTextBytes)
                    {
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed(byte *ptr2 = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PlainTextPtr, PlainTextBytes, 0, PlainTextSize);
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                // Get random bytes for salt
                                var    RNG       = new RNGCryptoServiceProvider();
                                byte[] SaltBytes = new byte[16];
                                RNG.GetBytes(SaltBytes);

                                // PBKDF2 key stretching
                                var DerivedPassword = new Rfc2898DeriveBytes(PasswordBytes, SaltBytes, iterations);

                                // Encryption with 128bit AES (using 192 or 256 bit isn't a good idea because Rfc2898DeriveBytes uses SHA-1, a 160 bit algorithm,
                                // so it's not recommended to take out more than 160 bits (increases time required to hash, but not time required to verify
                                // a hash, which means a defender does extra work but an attacker doesn't have to...Google it for reasons)
                                using (RijndaelManaged SymmetricKey = new RijndaelManaged()) {
                                    SymmetricKey.GenerateIV();
                                    SymmetricKey.Key  = DerivedPassword.GetBytes(16);
                                    SymmetricKey.Mode = CipherMode.CBC;
                                    using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor())
                                    {
                                        using (MemoryStream MemStream = new MemoryStream())
                                        {
                                            using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
                                            {
                                                CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
                                                CryptoStream.FlushFinalBlock();

                                                Result = $"e!2!{iterations}!{Convert.ToBase64String(SaltBytes)}!{Convert.ToBase64String(SymmetricKey.IV)}!{Convert.ToBase64String(MemStream.ToArray())}";
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                Array.Clear(PlainTextBytes, 0, PlainTextSize);

                                // Ensure managed array is cleared
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
            }
            finally
            {
                // Ensure unmanaged memory is released.
                if (PlainTextPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PlainTextPtr);
                }

                // Ensure unmanaged memory is released.
                if (PasswordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                }
            }

            return(Result);
        }
Exemple #7
0
        public void LoadFromProtectedString(string protectedString, RMSecureString password)
        {
            Clear();

            if (protectedString.StartsWith("e"))
            {
                LoadFromEncryptedString(protectedString, password);
            }
            else if (protectedString.StartsWith("p"))
            {
                // Trim leading 'p', which is just an indicator to say that this is an encrypted and not a protected string
                protectedString = protectedString.Substring(1);

                IntPtr PasswordPtr = IntPtr.Zero;

                try
                {
                    // Get the secure password string into a memory buffer
                    PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                    int PasswordSize = password.Length * sizeof(byte);

                    // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                    unsafe
                    {
                        byte[] Decrypted = null;
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed (byte* ptr = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                if (PasswordSize == 0)
                                {
                                    Decrypted = ProtectedData.Unprotect(Convert.FromBase64String(protectedString), null, DataProtectionScope.CurrentUser);
                                }
                                else
                                {
                                    Decrypted = ProtectedData.Unprotect(Convert.FromBase64String(protectedString), PasswordBytes, DataProtectionScope.CurrentUser);
                                }

                                for (int i = 0; i < Decrypted.Length; i++)
                                {
                                    if (_SecureStringSupported)
                                    {
                                        ((SecureString)_SecureString).AppendChar((char)Decrypted[i]);
                                    }
                                    else
                                    {
                                        ((StringBuilder)_SecureString).Append((char)Decrypted[i]);
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                if (Decrypted != null) Array.Clear(Decrypted, 0, Decrypted.Length);
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
                finally
                {
                    // Ensure unmanaged memory is released.
                    if (PasswordPtr != IntPtr.Zero)
                    {
                        Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                    }
                }
            }
        }
Exemple #8
0
        public void LoadFromEncryptedString(string encryptedString, RMSecureString password)
        {
            Clear();

            if (encryptedString.StartsWith("p"))
            {
                LoadFromProtectedString(encryptedString, password);
            }
            else if (encryptedString.StartsWith("e"))
            {
                // Trim leading 'e', which is just an indicator to say that this is an encrypted and not a protected string
                encryptedString = encryptedString.Substring(1);

                IntPtr PasswordPtr = IntPtr.Zero;

                try
                {
                    // Get the secure password string into a memory buffer
                    PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                    int PasswordSize = password.Length * sizeof(byte);

                    // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                    unsafe
                    {
                        byte[] Decrypted = null;
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed (byte* ptr = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(PasswordBytes, Encoding.ASCII.GetBytes("RMSecureString"), "SHA512", 12345);
                                using (RijndaelManaged SymmetricKey = new RijndaelManaged())
                                {
                                    SymmetricKey.Mode = CipherMode.CBC;
                                    using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(DerivedPassword.GetBytes(32), DerivedPassword.GetBytes(16)))
                                    {
                                        using (MemoryStream MemStream = new MemoryStream(Convert.FromBase64String(encryptedString)))
                                        {
                                            using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read))
                                            {
                                                byte[] DecryptedByte = new byte[1];

                                                int ByteCount = CryptoStream.Read(DecryptedByte, 0, 1);
                                                while (ByteCount > 0)
                                                {
                                                    if (_SecureStringSupported)
                                                    {
                                                        ((SecureString)_SecureString).AppendChar((char)DecryptedByte[0]);
                                                    }
                                                    else
                                                    {
                                                        ((StringBuilder)_SecureString).Append((char)DecryptedByte[0]);
                                                    }
                                                    ByteCount = CryptoStream.Read(DecryptedByte, 0, 1);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                if (Decrypted != null) Array.Clear(Decrypted, 0, Decrypted.Length);
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
                finally
                {
                    // Ensure unmanaged memory is released.
                    if (PasswordPtr != IntPtr.Zero)
                    {
                        Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                    }
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Encrypt the current SecureString with the ProtectData API, returning the computed value as a base64 string
        /// </summary>
        /// <returns>A base64 encoded string of the protected version of the current SecureString</returns>
        /// <remarks>Based on the code from Sly Gryphon's comment at http://weblogs.asp.net/pglavich/archive/2006/10/29/Secure-TextBox-Updated.aspx </remarks>
        public string GetProtectedString(RMSecureString password)
        {
            string Result = "";

            IntPtr PlainTextPtr = IntPtr.Zero;
            IntPtr PasswordPtr = IntPtr.Zero;

            try
            {
                // Get the secure plaintext string into a memory buffer
                if (_SecureStringSupported)
                {
                    PlainTextPtr = Marshal.SecureStringToGlobalAllocAnsi((SecureString)_SecureString);
                }
                else
                {
                    PlainTextPtr = Marshal.StringToHGlobalAnsi(((StringBuilder)_SecureString).ToString());
                }
                int PlainTextSize = this.Length * sizeof(byte);

                // Get the secure password string into a memory buffer
                PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                int PasswordSize = password.Length * sizeof(byte);

                // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                unsafe
                {
                    byte[] PlainTextBytes = new byte[PlainTextSize];
                    fixed (byte* ptr1 = PlainTextBytes)
                    {
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed (byte* ptr2 = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PlainTextPtr, PlainTextBytes, 0, PlainTextSize);
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                if (PasswordSize == 0)
                                {
                                    Result = "p" + Convert.ToBase64String(ProtectedData.Protect(PlainTextBytes, null, DataProtectionScope.CurrentUser));
                                }
                                else
                                {
                                    Result = "p" + Convert.ToBase64String(ProtectedData.Protect(PlainTextBytes, PasswordBytes, DataProtectionScope.CurrentUser));
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                Array.Clear(PlainTextBytes, 0, PlainTextSize);

                                // Ensure managed array is cleared
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
            }
            finally
            {
                // Ensure unmanaged memory is released.
                if (PlainTextPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PlainTextPtr);
                }

                // Ensure unmanaged memory is released.
                if (PasswordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                }
            }

            return Result;
        }
Exemple #10
0
        public string GetEncryptedString(RMSecureString password)
        {
            string Result = "";

            IntPtr PlainTextPtr = IntPtr.Zero;
            IntPtr PasswordPtr = IntPtr.Zero;

            try
            {
                // Get the secure plaintext string into a memory buffer
                if (_SecureStringSupported)
                {
                    PlainTextPtr = Marshal.SecureStringToGlobalAllocAnsi((SecureString)_SecureString);
                }
                else
                {
                    PlainTextPtr = Marshal.StringToHGlobalAnsi(((StringBuilder)_SecureString).ToString());
                }
                int PlainTextSize = this.Length * sizeof(byte);

                // Get the secure password string into a memory buffer
                PasswordPtr = Marshal.SecureStringToGlobalAllocAnsi(password.GetSecureText());
                int PasswordSize = password.Length * sizeof(byte);

                // Pin the array, copy data in, use it, and then make sure it is clear before unpinning.
                unsafe
                {
                    byte[] PlainTextBytes = new byte[PlainTextSize];
                    fixed (byte* ptr1 = PlainTextBytes)
                    {
                        byte[] PasswordBytes = new byte[PasswordSize];
                        fixed (byte* ptr2 = PasswordBytes)
                        {
                            try
                            {
                                Marshal.Copy(PlainTextPtr, PlainTextBytes, 0, PlainTextSize);
                                Marshal.Copy(PasswordPtr, PasswordBytes, 0, PasswordSize);

                                PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(PasswordBytes, Encoding.ASCII.GetBytes("RMSecureString"), "SHA512", 12345);
                                using (RijndaelManaged SymmetricKey = new RijndaelManaged())
                                {
                                    SymmetricKey.Mode = CipherMode.CBC;
                                    using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(DerivedPassword.GetBytes(32), DerivedPassword.GetBytes(16)))
                                    {
                                        using (MemoryStream MemStream = new MemoryStream())
                                        {
                                            using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
                                            {
                                                CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
                                                CryptoStream.FlushFinalBlock();

                                                Result = "e" + Convert.ToBase64String(MemStream.ToArray());
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Ensure managed array is cleared
                                Array.Clear(PlainTextBytes, 0, PlainTextSize);

                                // Ensure managed array is cleared
                                Array.Clear(PasswordBytes, 0, PasswordSize);
                            }
                        }
                    }
                }
            }
            finally
            {
                // Ensure unmanaged memory is released.
                if (PlainTextPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PlainTextPtr);
                }

                // Ensure unmanaged memory is released.
                if (PasswordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocAnsi(PasswordPtr);
                }
            }

            return Result;
        }