安全编码之-堆检查-SecureString

代码检测时会出现堆检查问题:

问题描述:

摘要

以不安全的方式存储敏感数据使得可以通过检查堆来提取数据。

解释

存储在内存中的敏感数据(如密码、社会安全号码、信用卡号码等)

如果存储在托管字符串对象中,则可能泄漏。字符串对象没有被钉住,所以垃圾

收集器可以随意重新定位这些对象,并在内存中留下多个副本。这些对象不是

默认情况下加密,所以任何人都可以读取进程的内存将能够看到的内容。

此外,如果进程的内存被交换到磁盘,则字符串的未加密内容将被删除。

写入交换文件。最后,由于字符串对象是不可变的,因此移除字符串的值。

只能由CLR垃圾收集器完成。垃圾回收器不需要运行。

除非CLR内存不足,所以不能保证何时进行垃圾回收。

在应用程序崩溃的情况下,应用程序的内存转储可能会显示敏感数据。

Example 1: The following method returns a password from the console and stores it in an insecure String
object.
public static void UseSecureString(SecureString ss)
{
 IntPtr ssAsIntPtr = Marshal.SecureStringToGlobalAllocUnicode(ss);
 String ssAsString = Marshal.PtrToStringUni(ssAsIntPtr);
 // work with ssAsString
}
Recommendation
Instead of working with the contents of a secure string by converting it to a String, use the Read-family of
methods in the Marshal class.
Example 2: The following method returns a password from the console and stores it in a SecureString
object and is manipulated by the Marshal class.
static void ManipulateSecureString()
{
 // SecureString, with some data
 SecureString ss = new SecureString();
 ss.AppendChar('a');
 ss.AppendChar('s');
 ss.AppendChar('d');
 ss.AppendChar('f');
 // copy data as unicode character array to a buffer in unmanaged space
 IntPtr ssAsIntPtr = Marshal.SecureStringToGlobalAllocUnicode(ss);
 for (Int32 i = 0; i < ss.Length; i++)
 {
 // multiply 2 because Unicode chars are 2 bytes wide
 Char ch = (Char)Marshal.ReadInt16(ssAsIntPtr, i * 2);
 // do something with each char
 }
 // don't forget to free it at the end
 Marshal.ZeroFreeGlobalAllocUnicode(ssAsIntPtr);
}

解决方式我是采用SecureString的数据类型:

正常的String类型值,在脱离开作用域之后,其值在内存中并不会被立即销毁,这时如果有人恶意扫描你的内存,程序中所保存的机密信息就会暴露;于是就有了System.Security.SecureString,SecureString表示一个应保密的文本,它在初始化时就已被加密,并且脱离作用域后会被立即销毁;

可以参考:https://www.cnblogs.com/Andrew-XinFei/p/5287948.htm

String类型和SecureString的相互转换:

        /// <summary>
        /// SecureString 转 string
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static String SecureStringToString(SecureString value)
        {
            IntPtr bstr = Marshal.SecureStringToBSTR(value);
            try
            {
                return Marshal.PtrToStringBSTR(bstr);
            }
            finally
            {
                Marshal.FreeBSTR(bstr);
            }
        }

        /// <summary>  
        /// Demonstrate how to convert String into SecureString   
        /// </summary>  
        public static SecureString StringToSecureString(String value)
        {
            SecureString password = new SecureString();
            char[] pass = value.ToCharArray();
            for (int i = 0; i < pass.Length; i++)
            {
                password.AppendChar(pass[i]);
            }
            return password;
        }  

如果这样改不掉的话,也可以直接改变量命名。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值