继续SecureString
上回写了关于SecureString的特征和为什么我们要使用它,这篇继续研究研究这个SecureString。**主要内容:**- SecureString与String之间的转换 - SecureString的基本操作 - 如何销毁一个String?##SecureString与String之间的转换 ###SecureString --> String的转换我们可以使用[Marshal类](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal(v=vs.110).aspx)提供的一些方法进行这个转换。Marshal类并不支持直接将`SecureString`转成托管的`System.String`对像,它提供的方法只能将`SecureString`转成一些非托管的字符串类型。我们需要再做一次转换才能得到`System.String`对象。所以基本的转换思路是这样的:*SecureString --> BSTR/Unicode/ANSI --> System.String*下面是代码,特别需要注意的地方是,我们一定要把非托管的字符串正确的释放掉。所以`Marshal.ZeroFreeBSTR`放在`Finally`块里确保一定会被执行。``` IntPtr bstr = IntPtr.Zero; try {bstr = Marshal.SecureStringToBSTR(sstr);var str = Marshal.PtrToStringBSTR(bstr);//处理字符串 } finally {Marshal.ZeroFreeBSTR(bstr);} ```**BSTR/Unicode/ANSI有啥区别?**我们看一下`Marshal`的方法列表就知道`Marshal`可以将`SecureString`转换成五种不同的字符串类型:`BSTR`,`CoTaskMemAnsi`,`CoTaskMemUnicode`, `GlobalAllocAnsi`, `GlobalAllocUnicode`。我当初有一个疑问就是这样子不同的类型转换有啥区别,我后来得出的结论是如果你只是想得到托管的`System.String`类型的话你选哪个作为中间变量都无所谓,只要用完释放资源就行了。###String --> SecureString的转换`SecureString`不接受`String`去构造一个对象,我们有两种方式可以将`String`转成`SecureString`。1. 通过AppendChar方法把`String`对象中的字符一个一个添加到`SecureString`后面。2. 虽然`SecureString`不接受`String`来构造一个对象,但是它接受一个字符指针来构造一个对象。所以我们可以取的指向`String`对象的非托管`char*`指针来构造。``` string str = "zhengyi.me"; unsafe {fixed (char* p_str = str){SecureString sstr = new SecureString(p_str, str.Length);sstr.MakeReadOnly();} } ```##SecureString的基本操作详情参考 [SecureString Class in MSDN](http://msdn.microsoft.com/en-us/library/system.security.securestring(v=vs.110).aspx)##如何销毁一个String对象?进一步思考一下,我们引入`SecureString`就是为了让敏感信息不在内存中裸奔。但是目前的.NET Framework提供的接口对`SecureString`的支持很有限,我们总会需要在某一小段时间内将其转换为`String`对象进行一些处理。那我们能不能让这些`String`对象*阅后即焚*呢?在C++中我们如果要销毁一个字符串的话,无非就是把字符串所在的内存memset成0,然后将这块字符串的内存释放掉。但是在.NET中的话我们主要会遇到这么两个问题:- 众所周知,Java和.NET中的String类型是[不可变的](http://msdn.microsoft.com/zh-cn/library/362314fe.aspx)(immutable)。我们如何将其中的内容重置掉?- .NET中,String是一个[引用类型](http://msdn.microsoft.com/zh-cn/library/362314fe.aspx),所以String实例时会存在于堆上的。那么在一次GC以后如果进行了内存的压缩,那么String实例可能在内存上会被移动。所以也就不方面释放内存。**如何破?**- 虽然说`String`在.NET中是不可变的,但是.NET中有一种unsafe的机制能够让我们像在C++中一样写*不安全代码*(使用指针的代码)。- fixed关键字可以防止GC去在内存中挪动变量。基本的代码就像下面这样:``` unsafe {//利用fixed关键字将字符串pin在内存上,确保其不会挪动而出现多个拷贝fixed(char* c = str){// 处理字符串// 利用unsafe的代码遍历字符串将其内容重置for(int i = 0; i < str.Length; i++){c[i] = '\0';}} } ```##总之 如同我在前篇文章中写的,我们所做的所有的这一切只是说提高了获取密码的难度和所需的时间。因为如果有人都能够拿到你的程序的内存的话,他可以干很多很多事情。##引用: [1] 关于使用SecureString的一些介绍:http://blogs.msdn.com/b/fpintos/archive/2009/06/12/how-to-properly-convert-securestring-to-string.aspx[2] 还不错的关于SecureString的一些讨论: http://bytes.com/topic/c-sharp/answers/583441-destroy-string
转载于:https://www.cnblogs.com/imjustice/p/more_about_secureString.html
继续SecureString相关推荐
- 建议118:使用SecureString保存密钥等机密字符串
建议118:使用SecureString保存密钥等机密字符串 托管代码中的字符串是一类特殊的对象,它们不可用被改变.每次使用System.String类张的方法之一时,或者使用此类型进行运算时(如赋值 ...
- Windows Server 8 Beta 初体验之三 Active Directory
Windows Server系统,随着版本的升级,很多功能越来越依赖于Active Directory,越来越离不开Active Directory,所以在体验Windows Server 8 Bet ...
- Windows Admin Center 高可用部署
本文老王将为大家实作Windows Admin Center的高可用部署,相信有了高可用的架构支持将更进一步推进该产品的落地 环境介绍 08dc2 lan 10.0.0.2 255.0.0.0 16s ...
- [转]使用 .NET Framework 2.0 在您的应用程序中支持证书
NET 安全 使用 .NET Framework 2.0 在您的应用程序中支持证书 Dominick Baier 本文讨论: Windows 证书存储区 .NET 中的证书类 验证.SSL.Web 服 ...
- sqlserver 无法远程连接到服务器,SQLServer2019无法连接远程服务器
PS:首先其他人的电脑是可以连接 这台服务器的,就我这电脑不行(连接本地是没有问题的),服务和Tcp都启用了 [百度过一些方法,并没有解决] 详细信息: 无法连接到 'ip地址' 在与 SQL Ser ...
- .NET FrameWork 4.0 新特性
请注意,.NET框架4引入了一个改进的安全模式.有关该内容的更多的信息,请参阅文章<.NET框架4中的安全变化>. 具体来说,本文中将介绍.NET框架4的如下一些新功能和改进特征: 应用程 ...
- 【网络安全】HTB靶机渗透系列之Sniper
介绍 Sniper是一个中等难度的靶机,知识点涉及本地文件包含利用.远程文件包含利用.凭证制作.恶意chm文件利用等. 通关思维导图 侦查 端口探测 首先使用 nmap 进行端口扫描 nmap -Pn ...
- windos 为什么会突然服务停止了_Windows服务异常自动关闭
一个Windows服务程序,在其他服务器运行都是正常的,今天在新服务器中运行,出现未知异常. 1.查看系统日志:自定义视图--管理日志 2.日志内容,比如 - - 1026 2 0 0x8000000 ...
- Winform中实现文件另存为后并打开文件
场景 在Winform程序中点击按钮实现Excel导出,会打开对话框,文件另存为之后自动打开文件. Process.Start Method 重载 Start() 启动(或重用)此 Process ...
- C#中使用Process调取Windows中的进程(应用程序)
场景 效果 System.Diagnostics.Process 提供对本地和远程进程的访问权限并使你能够启动和停止本地系统进程. 示例代码 using System; using System.Di ...
最新文章
- vue中 静态文件引用注意事项
- 分享Laravel中blade页面更改没有及时显示在页面的问题解决方案
- 适配器模式源码解析(jdk+spring+springjpa+springmvc)
- python冷知识_python冷知识
- django-模板语言dtl-render
- 重启手机出现机器人加一个叹号_印度科幻脑洞高能!《宝莱坞机器人2.0》内地定档...
- C++——fcntl
- 惯性导航算法(二)-欧拉角法(下)+方向余弦矩阵(上)
- 智能计算机与应用是核心期刊吗,人工智能的核心期刊都有哪些
- ML笔记:预训练(pre-training/trained)与微调(fine tuning)
- 网站被劫持怎么办,怎么解决?
- 华为HCNA笔记-TO-BE-CONTINUED
- 大数据时代最全的医学公共数据库合集整理
- vue页面背景颜色修改
- 平面设计中负空间的意思是什么?如何设计?
- 【RK3399 GMAC】Linux Debian9 gmac 主控输出clk ,即output模式
- 编写java的软件——Myeclipse,以及反编译的用法.
- 蓝牙鼠标卡顿,蓝牙与wifi冲突解决方式
- Nginx - 静态网站;负载均衡;静态代理;动静分离;虚拟主机
- 电脑计算机提示msvcr100.dll丢失如何修复,msvcr100.dll丢失的解决方法