gpt4 book ai didi

C# SecureString 问题

转载 作者:IT王子 更新时间:2023-10-29 04:21:04 25 4
gpt4 key购买 nike

有没有什么方法可以在不包含安全性的情况下获取 SecureString 的值?例如,在下面的代码中,只要您执行 PtrToStringBSTR,字符串就不再安全,因为字符串是不可变的,并且垃圾回收对于字符串来说是不确定的。

IntPtr ptr = Marshal.SecureStringToBSTR(SecureString object);
string value = Marshal.PtrToStringBSTR(ptr);

如果有办法获取非托管 BSTR 字符串的 char[] 或 byte[] 会怎么样?这是否意味着垃圾收集更可预测(因为您将使用 char[] 或 byte[] 而不是字符串?这个假设是否正确,如果是这样,您将如何取回 char[] 或 byte[]?

最佳答案

这是我专门为此目的编写的一个类。它是完全、100% 防黑客的吗?不 - 要使应用程序 100% 安全,您几乎无能为力,但是如果您需要将 SecureString 转换为 String<,则此类会尽可能地保护您自己.

下面是你如何使用这个类:

using(SecureStringToStringMarshaler sm = new SecureStringToStringMarshaler(secureString))
{
// Use sm.String here. While in the 'using' block, the string is accessible
// but pinned in memory. When the 'using' block terminates, the string is zeroed
// out for security, and garbage collected as usual.
}

这是类

/// Copyright (C) 2010 Douglas Day
/// All rights reserved.
/// MIT-licensed: http://www.opensource.org/licenses/mit-license.php

using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace DDay.Base
{
public class SecureStringToStringMarshaler : IDisposable
{
#region Private Fields

private string _String;
private SecureString _SecureString;
private GCHandle _GCH;

#endregion

#region Public Properties

public SecureString SecureString
{
get { return _SecureString; }
set
{
_SecureString = value;
UpdateStringValue();
}
}

public string String
{
get { return _String; }
protected set { _String = value; }
}

#endregion

#region Constructors

public SecureStringToStringMarshaler()
{
}

public SecureStringToStringMarshaler(SecureString ss)
{
SecureString = ss;
}

#endregion

#region Private Methods

void UpdateStringValue()
{
Deallocate();

unsafe
{
if (SecureString != null)
{
int length = SecureString.Length;
String = new string('\0', length);

_GCH = new GCHandle();

// Create a CER (Contrained Execution Region)
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// Pin our string, disallowing the garbage collector from
// moving it around.
_GCH = GCHandle.Alloc(String, GCHandleType.Pinned);
}

IntPtr stringPtr = IntPtr.Zero;
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(
delegate
{
// Create a CER (Contrained Execution Region)
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
stringPtr = Marshal.SecureStringToBSTR(SecureString);
}

// Copy the SecureString content to our pinned string
char* pString = (char*)stringPtr;
char* pInsecureString = (char*)_GCH.AddrOfPinnedObject();
for (int index = 0; index < length; index++)
{
pInsecureString[index] = pString[index];
}
},
delegate
{
if (stringPtr != IntPtr.Zero)
{
// Free the SecureString BSTR that was generated
Marshal.ZeroFreeBSTR(stringPtr);
}
},
null);
}
}
}

void Deallocate()
{
if (_GCH.IsAllocated)
{
unsafe
{
// Determine the length of the string
int length = String.Length;

// Zero each character of the string.
char* pInsecureString = (char*)_GCH.AddrOfPinnedObject();
for (int index = 0; index < length; index++)
{
pInsecureString[index] = '\0';
}

// Free the handle so the garbage collector
// can dispose of it properly.
_GCH.Free();
}
}
}

#endregion

#region IDisposable Members

public void Dispose()
{
Deallocate();
}

#endregion
}
}

此代码要求您可以编译不安全 代码,但它的效果非常好。

问候,

-道格

关于C# SecureString 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1800695/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com