Sar*_*els 5 c# arrays encryption rsa securestring
我有一个方法当前返回从字节数组转换而来的字符串:
public static readonly UnicodeEncoding ByteConverter = new UnicodeEncoding();
public static string Decrypt(string textToDecrypt, string privateKeyXml)
{
if (string.IsNullOrEmpty(textToDecrypt))
{
throw new ArgumentException(
"Cannot decrypt null or blank string"
);
}
if (string.IsNullOrEmpty(privateKeyXml))
{
throw new ArgumentException("Invalid private key XML given");
}
byte[] bytesToDecrypt = Convert.FromBase64String(textToDecrypt);
byte[] decryptedBytes;
using (var rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(privateKeyXml);
decryptedBytes = rsa.Decrypt(bytesToDecrypt, FOAEP);
}
return ByteConverter.GetString(decryptedBytes);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试更新此方法以返回 a ,但在将from的返回值转换为 时SecureString遇到问题。我尝试了以下方法:RSACryptoServiceProvider.Decryptbyte[]SecureString
var secStr = new SecureString();
foreach (byte b in decryptedBytes)
{
char[] chars = ByteConverter.GetChars(new[] { b });
if (chars.Length != 1)
{
throw new Exception(
"Could not convert a single byte into a single char"
);
}
secStr.AppendChar(chars[0]);
}
return secStr;
Run Code Online (Sandbox Code Playgroud)
然而,使用此 SecureString 相等测试器,结果与根据原始未加密文本构造的结果SecureString不同。SecureString我的加密和解密方法以前工作过,当时我只是string在任何地方使用,而且我还测试了SecureString相等代码,所以我很确定这里的问题是我如何尝试转换byte[]为SecureString. SecureString我是否应该采取另一条路线来使用 RSA 加密,以便在解密时可以恢复 a ?
编辑:我不想将字节数组转换为常规字符串,然后将该字符串填充到 a 中SecureString,因为这似乎违背了首先使用 a 的目的。SecureString但是,Decrypt返回byte[]然后我尝试将该字节数组填充到 a 中是否也很糟糕SecureString?我的猜测是,如果Decrypt返回 a byte[],那么这是传递敏感信息的安全方式,因此将数据的一种安全表示形式转换为另一种安全表示形式似乎没问题。
根据编码大猩猩的回答Decrypt,我在我的方法中尝试了以下方法:
string decryptedString1 = string.Empty;\nforeach (byte b in decryptedBytes)\n{\n decryptedString1 += (char)b;\n}\nstring decryptedString2 = ByteConverter.GetString(decryptedBytes);\nRun Code Online (Sandbox Code Playgroud)\n\n调试时,decryptedString1和decryptedString2不相等:
decryptedString1 "m\\0y\\0V\\0e\\0r\\0y\\0L\\0o\\0n\\0g\\0V\\03\\0r\\0y\\05\\03\\0c\\0r\\03\\07\\0p\\04\\0s\\0s\\0w\\00\\0r\\0d\\0!\\0!\\0!\\0"\ndecryptedString2 "myVeryLongV3ry53cr37p4ssw0rd!!!"\nRun Code Online (Sandbox Code Playgroud)\n\n所以看起来我可以遍历数组byte[],直接转换为char,然后跳过\\0字符。不过,就像 Coding Gorilla 所说的那样,这似乎再次在一定程度上违背了这一点SecureString,因为敏感数据以小块的形式漂浮在内存中byte。对于直接RSACryptoServiceProvider.Decrypt返回有什么建议SecureString吗?
编辑:是的,这有效:
\n\nvar secStr = new SecureString();\nforeach (byte b in decryptedBytes)\n{\n var c = (char)b;\n if (\'\\0\' == c)\n {\n continue;\n }\n secStr.AppendChar(c);\n}\nreturn secStr;\nRun Code Online (Sandbox Code Playgroud)\n\n编辑:更正:这适用于普通的旧英语字符串。加密然后尝试解密字符串"\xe6\xa8\x99\xe6\xba\x96\xe8\xaa\x9e \xe6\x98\x8e\xe6\xb2\xbb\xe7\xb6\xad\xe6\x96\xb0 english \xe3\x82\x84\xe3\x81\xa3\xe3\x81\x9f"无法按预期工作,因为使用此foreach (byte b in decryptedBytes)技术生成的解密字符串与原始未加密字符串不匹配。
编辑:对两者使用以下作品:
\n\nvar secStr = new SecureString();\nforeach (char c in ByteConverter.GetChars(decryptedBytes))\n{\n secStr.AppendChar(c);\n}\nreturn secStr;\nRun Code Online (Sandbox Code Playgroud)\n\n这仍然在内存中留下了密码的字节数组和字符数组,这很糟糕。也许我应该找到另一个返回SecureString. :/