public ProtectedMemoryBlob(ISecret secret)
        {
            if (secret == null)
            {
                throw new ArgumentNullException("secret");
            }

            ProtectedMemoryBlob other = secret as ProtectedMemoryBlob;

            if (other != null)
            {
                // Fast-track: simple deep copy scenario.
                this._localAllocHandle = other._localAllocHandle.Duplicate();
                this._plaintextLength  = other._plaintextLength;
            }
            else
            {
                // Copy the secret to a temporary managed buffer, then protect the buffer.
                // We pin the temp buffer and zero it out when we're finished to limit exposure of the secret.
                byte[] tempPlaintextBuffer = new byte[secret.Length];
                fixed(byte *pbTempPlaintextBuffer = tempPlaintextBuffer)
                {
                    try
                    {
                        secret.WriteSecretIntoBuffer(new ArraySegment <byte>(tempPlaintextBuffer));
                        _localAllocHandle = Protect(pbTempPlaintextBuffer, (uint)tempPlaintextBuffer.Length);
                        _plaintextLength  = (uint)tempPlaintextBuffer.Length;
                    }
                    finally
                    {
                        UnsafeBufferUtil.SecureZeroMemory(pbTempPlaintextBuffer, tempPlaintextBuffer.Length);
                    }
                }
            }
        }
        public static ProtectedMemoryBlob Random(int numBytes)
        {
            CryptoUtil.Assert(numBytes >= 0, "numBytes >= 0");

            if (numBytes == 0)
            {
                byte dummy;
                return(new ProtectedMemoryBlob(&dummy, 0));
            }
            else
            {
                // Don't use CNG if we're not on Windows.
                if (!OSVersionUtil.IsBCryptOnWin7OrLaterAvailable())
                {
                    return(new ProtectedMemoryBlob(ManagedGenRandomImpl.Instance.GenRandom(numBytes)));
                }

                byte[] bytes = new byte[numBytes];
                fixed(byte *pbBytes = bytes)
                {
                    try
                    {
                        BCryptUtil.GenRandom(pbBytes, (uint)numBytes);
                        return(new ProtectedMemoryBlob(pbBytes, numBytes));
                    }
                    finally
                    {
                        UnsafeBufferUtil.SecureZeroMemory(pbBytes, numBytes);
                    }
                }
            }
        }