我有一个带有“秘密”(例如密码)的应用程序
我不想将此秘密本地存储在用户可访问的上下文文件中,因此我计划通过HTTPS从服务器按需检索它。
出于明显的原因,我也不希望它在内存中可见(例如,从崩溃日志中可见),因此我将机密存储在SecureString中
但是,当我序列化SecureString时,结果仅显示明文字符串的长度,例如{"Length":4}
但是,如果我以明文形式传输密码,那么即使随后将其存储在SecureString中,该密码也将在内存中检索到的JSON中可见
是否有任何方法可以序列化SecureString或接收JSON并将纯文本字符串转换为SecureString而不需要存储在内存中的中间常规字符串?
在这种情况下,我必须存储/发送实际密码,而不是例如一次使用的一次性密钥:这超出了我的控制范围。我需要实际的纯文本密码才能访问其他服务,因此通常的“先哈希然后比较哈希”也不适用
答案 0 :(得分:0)
这是一个使用RSA加密将字符串发送给您拥有公钥的人的有效示例。在您的问题中,您希望服务器向客户端发送消息(密码),并让客户端安全地使用该密码,而不必担心中间的日志记录等。为此,您需要让客户端创建私钥文件并将公钥文件发送到服务器,然后服务器可以安全地进行通信。
可能有一些库使这种方式更容易。
[Test]
public void TestEncryption()
{
/////////////// Create Key Files ////////////////
RSACryptoServiceProvider provider = new RSACryptoServiceProvider(4096);
//Create the key files on disk and distribute them to sender / reciever
var publicKey = provider.ToXmlString(false);
var privateKey = provider.ToXmlString(true);
/////////////// Actual Test ////////////////
//send with the public key
byte[] sent = Send("hey",publicKey);
//cannot receive with public key
var ex = Assert.Throws<CryptographicException>(()=>Receive(sent, publicKey));
StringAssert.Contains("Key does not exist",ex.Message);
//but can with private key
Assert.AreEqual("hey", Receive(sent,privateKey));
}
private Byte[] Send(string send, string publicKey)
{
using (RSACryptoServiceProvider rsaSender = new RSACryptoServiceProvider())
{
rsaSender.FromXmlString(publicKey);
return rsaSender.Encrypt(Encoding.ASCII.GetBytes(send), false);
}
}
private object Receive(byte[] sent, string privateKey)
{
using (RSACryptoServiceProvider rsaReceiver = new RSACryptoServiceProvider())
{
rsaReceiver.FromXmlString(privateKey);
return Encoding.ASCII.GetString(rsaReceiver.Decrypt(sent, false));
}
}