Brian said:
Hi, I want to copy the first 6 characters of a SecureString to a new
SecureString, leaving the old one unchanged.
If at all possible, avoid doing this. Change the code that creates the
original SecureString instead to also produce this string. It's very hard to
operate on SecureStrings after the fact (at least while maintaining security).
The SecureString constructor takes a char pointer and length, but how do I
get a the char pointer from the old SecureString ?
This is quickest, but it requires unsafe code:
SecureString s2;
IntPtr p = IntPtr.Zero;
try {
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally {
p = Marshal.SecureStringToGlobalAllocUnicode(s);
}
unsafe (char* c = (char*) p) {
s2 = new SecureString(c, 6);
}
} finally {
if (p != IntPtr.Zero) Marshal.ZeroFreeGlobalAllocUnicode(p);
}
Note that allocating is done in a constrained execution region (CER) to
prevent the possibility of an exception occurring between the allocation and
the assignment to p (yes, this is possible, and it would leave a leaked
unsecure copy of the string in memory). This may fire warnings if you're
using MDAs because the CER is technically invalid
(.SecureStringToGlobalAllocUnicode() is not marked with the appropriate
attribute). Still, as far as I can tell it's necessary.