gpt4 book ai didi

c# - 在 clickonce 应用程序中安全地存储服务帐户凭据

转载 作者:太空宇宙 更新时间:2023-11-03 12:36:55 25 4
gpt4 key购买 nike

我正在编写一个 ClickOnce 应用程序,它使用服务帐户凭据运行批处理文件进程。我需要存储服务帐户凭据,以便程序可以在运行进程之前将用户名/密码添加到 process.startinfo 属性。用户不知道此密码,因此不会提示他们输入密码。我相信这意味着我不能以这种方式存储散列和验证密码,我生成的散列值必须是可逆的,以便它可以将正确的密码添加到 startinfo 属性。我搜索了这个网站并提出了一个科学怪人类型的解决方案,但它不是很安全。目前,我使用此方法加密密码,存储加密值,然后在运行时使用 decrypt 方法获取密码(加密方法在运行时从不运行,我在调试时在 Visual Studio 中运行它,复制值,然后在下面的解密方法中使用该值):

// used to generate decrypted acct creds
private void EncryptText(string plaintext)
{
string outsrt = null;
RijndaelManaged aesAlg = null;

try
{
// generate key from secret and salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedsecret, _salt);

aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);

ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

using (MemoryStream mEncrypt = new MemoryStream())
{
// prepend the IV
mEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int));
mEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
using (CryptoStream csEncrypt = new CryptoStream(mEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
// write all data to the stream
swEncrypt.Write(plaintext);
}
}

outsrt = Convert.ToBase64String(mEncrypt.ToArray());
}
}
finally
{
if (aesAlg != null)
aesAlg.Clear();
}

Console.WriteLine(outsrt);
}

解密方法如下:

private string GetServiceAcctPW()
{

// Declare the RijndaelManaged object
// used to decrypt the data.
RijndaelManaged aesAlg = null;

// Declare the string used to hold
// the decrypted text.
string plaintext = null;

try
{
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedsecret, _salt);

// Create the streams used for decryption.
byte[] bytes = Convert.FromBase64String("EncryptedValueHere");
using (MemoryStream msDecrypt = new MemoryStream(bytes))
{
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
// Get the initialization vector from the encrypted stream
aesAlg.IV = ReadByteArray(msDecrypt);
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))

// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
catch(Exception e)
{
Console.WriteLine("Error decrypting password");
Console.WriteLine(e.StackTrace);
logger.WriteToLog(Logger.LogCodes.ERROR, "Error decrypting service account password");
MessageBox.Show("An error occurred while trying to start the installation process\nPlease contact the Service Desk for further assistance");
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}

return plaintext;
}

此代码工作正常,但是,我知道它不安全。我的代码审查人员说他能够在一个小时内使用 dotPeek 破解它,因为它只是添加了一层混淆。在应用程序中存储这些凭据的最佳/正确方法是什么?

最佳答案

加密 key 在专用服务器上。

密码连同要加密的 id 一起发送到服务器,并返回用于数据库存储的加密密码。

当需要密码时,会向带有 id 的专用服务器发出请求,并返回解密后的密码。

密码永远不会保存到磁盘,并且 key 永远不会在专用服务器上可用。

专用服务器有点像穷人的 HSM。

这是加密,不是散列。加密 key 与随机 IV 一起是 secret 的,它与专用服务器上的 id 一起保存。 key 不可用且与密码无关,因此没有比暴力破解加密 key 更好的攻击了,加密 key 本质上太大而无法被暴力破解。

服务器需要非常安全,只有几个两因素登录并且不能用于 Internet。

关于c# - 在 clickonce 应用程序中安全地存储服务帐户凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40598563/

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