Ejemplo n.º 1
0
        private void Initialize()
        {
            unsafe
            {
                // We are about to create an unencrypted version of our sensitive string and store it in memory.
                // Don't let anyone (GC) make a copy.
                // To do this, create a new gc handle so we can "pin" the memory.
                // The gc handle will be pinned and later, we will put info in this string.
                _gcHandle = new GCHandle();
                // insecurePointer will be temporarily used to access the SecureString
                var insecurePointer = IntPtr.Zero;
                System.Runtime.CompilerServices.RuntimeHelpers.TryCode code = delegate
                {
                    // create a new string of appropriate length that is filled with 0's
                    Value = new string((char)0, _secureString.Length);
                    // Even though we are in the ExecuteCodeWithGuaranteedCleanup, processing can be interupted.
                    // We need to make sure nothing happens between when memory is allocated and
                    // when _gcHandle has been assigned the value. Otherwise, we can't cleanup later.
                    // PrepareConstrainedRegions is better than a try/catch. Not even a threadexception will interupt this processing.
                    // A CER is not the same as ExecuteCodeWithGuaranteedCleanup. A CER does not have a cleanup.

                    Action alloc = delegate { _gcHandle = GCHandle.Alloc(Value, GCHandleType.Pinned); };
                    alloc.ExecuteInConstrainedRegion();

                    // Even though we are in the ExecuteCodeWithGuaranteedCleanup, processing can be interupted.
                    // We need to make sure nothing happens between when memory is allocated and
                    // when insecurePointer has been assigned the value. Otherwise, we can't cleanup later.
                    // PrepareConstrainedRegions is better than a try/catch. Not even a threadexception will interupt this processing.
                    // A CER is not the same as ExecuteCodeWithGuaranteedCleanup. A CER does not have a cleanup.
                    Action toBSTR = delegate { insecurePointer = Marshal.SecureStringToBSTR(_secureString); };
                    toBSTR.ExecuteInConstrainedRegion();

                    // get a pointer to our new "pinned" string
                    var value = (char *)_gcHandle.AddrOfPinnedObject();
                    // get a pointer to the unencrypted string
                    var charPointer = (char *)insecurePointer;
                    // copy
                    for (int i = 0; i < _secureString.Length; i++)
                    {
                        value[i] = charPointer[i];
                    }
                };
                System.Runtime.CompilerServices.RuntimeHelpers.CleanupCode cleanup = delegate
                {
                    // insecurePointer was temporarily used to access the securestring
                    // set the string to all 0's and then clean it up. this is important.
                    // this prevents sniffers from seeing the sensitive info as it is cleaned up.
                    if (insecurePointer != IntPtr.Zero)
                    {
                        Marshal.ZeroFreeBSTR(insecurePointer);
                    }
                };
                // Better than a try/catch. Not even a threadexception will bypass the cleanup code
                RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(code, cleanup, null);
            }
        }
Ejemplo n.º 2
0
 public static void ExecuteCodeWithGuaranteedCleanup(System.Runtime.CompilerServices.RuntimeHelpers.TryCode code, System.Runtime.CompilerServices.RuntimeHelpers.CleanupCode backoutCode, object userData)
 {
 }