It would be easy to do if you converted the SecureString
s to String
s first, but that defeats the very purpose of SecureString
, which is to not leave the sensitive information as a hanging string object in memory. You have to be careful to only work with byte arrays, and to zero-clear them afterwards.
<Extension()> _
Public Function Append(ByVal s1 As SecureString, ByVal s2 As SecureString) As SecureString
Dim b() As Byte
Dim p1 = Marshal.SecureStringToGlobalAllocUnicode(s1)
Try
Dim p2 = Marshal.SecureStringToGlobalAllocUnicode(s2)
Try
ReDim b(0 To s1.Length * 2 + s2.Length * 2 - 1)
Marshal.Copy(p1, b, 0, s1.Length * 2)
Marshal.Copy(p2, b, s1.Length * 2, s2.Length * 2)
Finally
Marshal.ZeroFreeGlobalAllocUnicode(p2)
End Try
Finally
Marshal.ZeroFreeGlobalAllocUnicode(p1)
End Try
Dim res = New SecureString()
For i As Integer = LBound(b) To UBound(b) Step 2
res.AppendChar(BitConverter.ToChar(b, i))
Next
res.MakeReadOnly()
Array.Clear(b, 0, b.Length)
Return res
End Function
Usage:
Dim result = SecureString1.Append(SecureString2)