SecureString的实例如何被分配和释放

分析问题

  System.Security.SecureString被设计用来保存一些机密的字符串,完成传统字符串所不能做到的工作。传统字符串以明码的形式分配在内存上,一个简单的内存读写软件可以轻易地捕获这些字符串,这在有些机密系统中是不被允许的。读者可能觉得对字符串加密会解决类似的问题,但事实上对字符串加密时字符串已经以明码的方式驻留在内存上很久了,对于该问题唯一的解决办法就是在字符串的获取过程中直接进行加密。SecureString的设计初衷就是解决该类问题。

  为了保证它的安全性,SecureString的分配不同于传统字符串,它是被分配在非托管内存上的。并且SecureString的对象从分配的一开始就以加密的形式存在。对SecureString的所有操作,无论添加、删除、插入等,都是逐字符进行的。在这些操作进行的时候,驻留在非托管内存上的安全字符串会被解密,然后再进行操作,最后进行加密。在操作的过程中确实有一小段时间字符串是处于明码状态的,但逐字符的机制让这段时间维持在非常短的区间内,以保证破解程序很难有机会读取明码的字符串。

  System.Security.SecureString实现了标准的Dispose/Finalize模式,这是因为其对象的分配是在非托管内存上,所以需要保证每个对象在作用域退出后将被释放掉。SecureString的释放方式是把其对象内存全部置0,而不仅仅是告诉CLR这一块内存可以分配,当然这样做仍然是为了确保安全。以下代码展示了System.Security.SecureString的使用方法。

  

using System;
using System.Security;
using System.Runtime.InteropServices;

namespace Test
{
    class UseSecureString
    {
        static void Main()
        {
            //Use using guarantee the Dispose method is invoked
            using (SecureString ss = new SecureString ())
            {
                //Only one character to visit SecureString object
                ss.AppendChar(‘a‘);
                ss.AppendChar(‘c‘);
                ss.AppendChar(‘d‘);
                ss.InsertAt(1,‘c‘);
                PrintSecureString(ss);
                Console.Read();
            }
        }

        //Print SecureString object
        unsafe static void PrintSecureString(SecureString ss)
        {
            char* buffer = null;
            try
            {
                buffer = (char*)Marshal.SecureStringToCoTaskMemUnicode(ss);
                for (int i = 0;*(buffer+i)!=‘\0‘; i++)
                {
                    Console.Write(*(buffer + i));
                }
                Console.Write("\r\n");
            }
            finally
            {
                //Release the memory object
                if (buffer!=null)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode((IntPtr)buffer);
                }
            }
        }
    }
}

注意

  为了显示SecureString的内容,程序需要访问非托管内存块,PrintSecureString方法使用了unsafe关键字,所以编译时需要添加/unsafe开发。项目-属性-生成-允许不安全代码。

  在以上代码中,程序分配了一个安全字符串类型,并且提供了一个打印安全字符的方法。其中使用了Marshal.SecureStringToTaskMemUnicode方法把安全字符串解密到非托管内存块中,读者需要注意的是,在使用非托管内存时要确保其被释放。

答案

  System.Security.SecureString提供了加密的字符串类型。其对象会被分配在非托管的内存中,并且以加密的形式保存。对于SecureString的操作都是逐字符的,SecureString会负责在操作时进行解密和加密。SecureString实现了标准的Dispose/Finalize方法,对象被释放时先被全部置0,以保证机密信息不会在内存中驻留过长时间。

  

  

SecureString的实例如何被分配和释放

时间: 2024-10-12 02:24:41

SecureString的实例如何被分配和释放的相关文章

ZFS空间管理(分配、释放原理)

一个文件系统的空间管理,常见的技术大致有两种,bitmap和tree方式. bitmap是将文件系统所有管辖的空间细化成block(windows叫cluster),每一个block对应一个二进制位,两种状态分别表示自由/已分配.将这些二进制位集合在一起,就是bitmap.当需要分配空间时,在bitmap中查找连续的自由位,分配后,再置成已分配就可以了:释放时,将对应位置为可分配即可. tree方式是以extent的记录来描述自由/已分配空间的状态,如果以表示自由空间的tree来说,有可能是由一

per-CPU分配和释放单页框

内核经常请求和释放单个页框.为了提升系统性能,每个内存管理区定义了一个"每CPU"页框高速缓存.所有"每CPU"高速缓存包含一些预先分配的页框,它们被用于满足本地CPU发出的单一内存请求. 为每个内存管理区和每CPU提供了两个高速缓存:一个热高速缓存,它存放页框中所包含的内容很可能就在CPU硬件高速缓存中:还有一个冷高速缓存. 在内存管理区中,分配单页使用per-cpu机制,分配多页使用伙伴算法,结构图如下: 1.相关结构体 zone结构体中pageset成员指向内

如何在MD(d)和MT(d)工程间正确分配和释放动态内存

MD(d)和MT(d) MD(d)和MT(d)是windows下VC开发的两个编译选项,表示程序的运行时库编译选项. /MT是"multithread, static version" 意思是多线程静态的版本,定义了它后,编译器把LIBCMT.lib安置到OBJ文件中,让链接器使用LIBCMT.lib 处理外部符号. /MD是"multithread- and DLL-specific version",意思是多线程DLL版本,定义了它后,编译器把MSVCRT.li

堆空间的分配与释放

堆空间的分配和释放 #include <stdlib.h> malloc.calloc.realloc.free malloc void *malloc(size_t size); 功能:在堆中分配 size 字节的连续空间 参数:size_字节数 返回值:成功返回分配空间的首地址,失败返回 NULL free void free(void *ptr); 功能:释放由 malloc.calloc.realloc 分配的空间 参数:ptr_空间的首地址 返回值:无 注意: 1.每个空间只能释放一

C 存储空间的分配和释放

存储空间的分配和释放 动态存储分配的数据结构 头文件  #include<stdlib.h> 用四个函数来进行动态储存分配{ malloc(),calloc(), realloc()},动态存储释放:free(). 1.malloc(),动态分配一段内存空间 void *malloc(unsigned int size) 用sizeof()来计算申请空间的大小 例:int *p=(int *)malloc(sizeof(int)) 申请一个Int类型长度的存储空间,并将分配的地址空间地址转化成

Delphi的分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同

转载自:http://www.cnblogs.com/qiusl/p/4028437.html?utm_source=tuicool 我估摸者内存分配+释放是个基础的函数,有些人可能没注意此类函数或细究,但我觉得还是弄明白好. 介绍下面内存函数之前,先说一下MM的一些过程,如不关心课忽略: TMemoryManger = record GetMem: function(Size: Integer): Pointer; FreeMem: function(P: Pointer): Integer;

c++跨动态库DLL的内存分配与释放问题

先说结论: 1.如果两个DLL(或者EXE调用DLL)的CRT链接均为MD,则可以跨动态库分配和释放,如果一个是MT,另外一个是MD则会有问题. 2.利用虚函数的动态绑定技术,动态绑定分配释放内存的new和delete等,可以解决这个问题,例如shared_ptr.但如果shared_ptr包装是vector等类型,在调用和被调用中都涉及到vector的修改的话,仍然会有问题,因为两个地方都会有释放和分配. 似乎最好的办法还是用原始指针加数组长度的方式传递. 参见下面两个文章. 1.跨DLL的内

c++动态内存分配与释放

一般变量的分配与释放 #include<iostream> using namespace std; int main() {     int *p = new int(4);     *p = 10;     cout << *p << endl;     delete p;     return 0; } 数组变量的分配与释放 #include #include<iostream> using namespace std; int main() {   

内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现

http://blog.csdn.net/pi9nc/article/details/23334659 注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料.此书出版较早,分析的版本为2.4.16,故出现的一些概念可能跟最新版本内核不同.