CodeExplorer Posted February 27, 2011 Posted February 27, 2011 .NET memory securityLoking under some encryption/decryption tutorial I've noticed that they use MemoryStream.ToArray(); MemoryStream.ToArray() is bad since will create a new byte array under memory – insted just use an UnmanagedMemoryStream and UnmanagedMemoryStream.GetBuffer()!But the contents of the UnmanagedMemoryStream buffer (you get him using GetBuffer()) will be still there even if I close the memory stream, set him to 0 and call System.GC.Collect()What is going on ?1. The memory is released : According to Microsof the object is destroyed when all its references are explicitly set to null or it goes out of scope.2. The contents is still there and probabily won't be overwrited by Framework whit other value!1.) 1st lame solution is to set each byte from buffer whit 0:for (int i=0;i< outStream.GetBuffer().Length;i++)outStream.GetBuffer()=0;2. Another solution could be to create of a secured MemoryStream which will always have the byte array encryted but this prove to be ineficient since at a point you may still need the whole byte buffer decrypted or the encryption/decryption algorithm doesn't suport partial encryption/decryption.The best solution is the double encryption : once encrypt the whole data and after that encrypt each subset of data.3.) Use Marshal.AllocHGlobal for alocating needed memory and use a pointer for accessing memory;// Allocate a block of unmanaged memoryIntPtr memptr = Marshal.AllocHGlobal(4);byte* pointer = (byte*)memptr.ToPointer(); pointer[0]=21; // set first byte whit 21byte firstbyte = pointer[0]; // get first byteMarshal.FreeHGlobal(memptr); // free the memory4. ) Build your own byte[] array:byte[] test = new byte[]{1,2,3,4};uint* pointer = null;int arraytable = 0;// we create a new byte array whit 4 bytesint newsize = 4;IntPtr memptr = Marshal.AllocHGlobal(8+newsize);// 8 bytes needed for structfixed ( byte* p = test){// real address from where byte[] startsint* bytearraystart = (int*)(p-8);arraytable = bytearraystart[0]; // get the Marshal.WriteInt32(memptr,0,arraytable);}Marshal.WriteInt32(memptr,4,newsize);Assembly loadedasm = Assembly.Load(test);Unfortunality .NET don't suport IntPtr to byte[] casting; we are only saved by reflection: replace the variable test whit memptr (of type IntPtr);
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now