[英]C# client - securing REST authentication tokens on client machine
Question i'd like to discuss about. 我想讨论的问题。
We have REST services (WCF) that after logon - a token is received and is sent to the client. 我们拥有REST服务(WCF),该服务在登录后-接收到令牌并将其发送给客户端。 HTTPS is of course defined.
HTTPS当然是定义的。
each request sends this token in the "Authorization" header. 每个请求都会在“授权”标头中发送此令牌。
The thing is, that if someone dumps the memory, he will be able to get the token and use it as he wishes. 问题是,如果有人转储了内存,他将能够获取令牌并按自己的意愿使用它。
we can secure this token only until the send, as we need to convert it to a C# string - which, can't be explicitly disposed. 我们只能在发送之前确保此令牌的安全,因为我们需要将其转换为C#字符串-无法显式处理。
so, there are 2 problems with this approach: 因此,此方法存在两个问题:
is there a recommended way of securing the token? 有建议的方法来保护令牌吗? maybe buffering the headers each request 1 character at a time?
也许缓冲标题每次一次请求1个字符?
Would love to hear your thoughts. 很想听听您的想法。
Your post is a little confusing, are you the client/consumer, or the service/provider? 您的帖子有点令人困惑,您是客户/消费者还是服务/提供商?
If you're the provider, you should be more concerned about having HTTPS enabled, you wouldn't believe how easy it is to steal tokens over the clear web and if your service is compromised, then having the memory dumped is still the least of your problems. 如果您是提供者,则应该更加关注启用HTTPS的情况,您不会相信在透明的网络上窃取令牌有多么容易,并且如果您的服务受到损害,那么转储内存仍然是最少的事情。你的问题。
That said, what you're looking for is SecureString
you can find more information on it here 也就是说,您正在寻找的是
SecureString
您可以在此处找到更多信息。
And here's a small example of how to make it work.... 这是一个如何使其工作的小例子。
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);
}
}
It's probably worth checking out the DPAPI whilst you're on the subject too... 当您也在研究该主题时,可能值得检查一下DPAPI ...
Here's one of my utility classes that makes use of it 这是我利用它的实用程序类之一
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.