问题我想讨论。
我们有REST服务(WCF),在登录后 - 收到一个令牌并发送到客户端。 HTTPS当然是定义的。
每个请求都在"授权"中发送此令牌。报头中。
问题是,如果有人转储内存,他将能够获得令牌并按照自己的意愿使用它。
我们只能在发送之前保护此令牌,因为我们需要将其转换为C#字符串 - 无法明确处理。
所以,这种方法存在两个问题:
是否有推荐的方法来保护令牌?也许缓冲标题每次请求1个字符?
很想听听你的想法。
答案 0 :(得分:0)
您的帖子有点令人困惑,您是客户/消费者,还是服务/提供商?
如果您是提供商,您应该更加关注启用HTTPS,您不会相信通过明确的网络窃取令牌是多么容易,如果您的服务受到损害,那么内存转储仍然是你的问题中最少的。
那就是说,您正在寻找的是SecureString
您可以找到有关它的更多信息here
这是一个如何使其发挥作用的小例子。
public void Example()
{
SecureString secureString = ConvertToSecureString("abc");
string normalString = ConvertToString(secureString);
Console.WriteLine (normalString);
}
// Secure it
public SecureString ConvertToSecureString(string password)
{
SecureString secureString = new SecureString();
foreach (char c in password.ToCharArray())
{
secureString.AppendChar(c);
}
return secureString;
}
// Unsecure it
public string ConvertToString(SecureString securePassword)
{
IntPtr unmanagedString = IntPtr.Zero;
try
{
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
在您关注这个主题时,可能值得查看DPAPI ...
这是我的一个使用它的实用程序类
public void DpapiExample()
{
// Adds a level of entropy to our encryption making our encrypted data more secure
string entropy = "603e0f3a0ef74faf93b5e6bc2c2f7c358107";
var dpapi = new Dpapi(entropy);
string textToEncrypt = "I'm a secret";
string encryptedText;
dpapi.TryEncrypt(textToEncrypt, out encryptedText);
Console.WriteLine ("Encrypting");
Console.WriteLine (textToEncrypt);
Console.WriteLine (encryptedText);
string decryptedText;
dpapi.TryDecrypt(encryptedText, out decryptedText);
Console.WriteLine ("\r\nDecrypting");
Console.WriteLine (encryptedText);
Console.WriteLine (decryptedText);
}
public class Dpapi
{
private readonly byte[] entropy;
public Dpapi(string entropy)
{
this.entropy = Encoding.UTF8.GetBytes(entropy);
}
public Dpapi(string entropy, Encoding encoding)
{
this.entropy = encoding.GetBytes(entropy);
}
public bool TryDecrypt(string encryptedString, out string decryptedString)
{
if (string.IsNullOrWhiteSpace(encryptedString))
{
throw new ArgumentNullException("encryptedString");
}
decryptedString = string.Empty;
try
{
byte[] encryptedBytes = Convert.FromBase64String(encryptedString);
byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, this.entropy, DataProtectionScope.LocalMachine);
decryptedString = Encoding.UTF8.GetString(decryptedBytes);
}
catch
{
return false;
}
return true;
}
public bool TryEncrypt(string unprotectedString, out string encryptedString)
{
if (string.IsNullOrWhiteSpace(unprotectedString))
{
throw new ArgumentNullException("unprotectedString");
}
encryptedString = string.Empty;
try
{
byte[] unprotectedData = Encoding.UTF8.GetBytes(unprotectedString);
byte[] encryptedData = ProtectedData.Protect(unprotectedData, this.entropy, DataProtectionScope.LocalMachine);
encryptedString = Convert.ToBase64String(encryptedData);
}
catch
{
return false;
}
return true;
}
}