C#学习教程:在ClickOnce应用程序中安全地存储服务帐户凭证我需要存储服务帐户凭据,以便程序可以在运行进程之前将用户名/密码添加到process.startinfo属性。用户不知道此密码,因此不会提示他们输入密码。我相信这意味着我不能以这种方式存储散列和验证密码,我生成的散列必须是可逆的,以便它可以将正确的密码添加到startinfo属性。我在该站点上进行了搜索,并提出了一种可行的科学怪人类型的解决方案,但它不是很安全。目前,我使用这种方法加密密码,存储加密值,然后在运行时使用解密方法获取密码(加密方法从不在运行时运行,我在调试时在VisualStudio中运行它,复制值,然后在下面的decrypt方法中使用Thisvalue)://用于生成解密的acctcredsprivatevoidEncryptText(stringplaintext){stringoutsrt=null;RijndaelManagedaesAlg=null;try{//从秘密和盐生成密钥Rfc2898DeriveByteskey=newRfc2898DeriveBsharedsecret,_salt);aesAlg=newRijndaelManaged();aesAlg.Key=key.GetBytes(aesAlg.KeySize/8);ICryptoTransform加密器=aesAlg.CreateEncryptor(aesAlg.Key,aesAlg.IV);using(MemoryStreammEncrypt=newMemoryStream()){//在IV前面加上mEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length),0,sizeof(int));mEncrypt.Write(aesAlg.IV,0,aesAlg.IV.Length);using(CryptoStreamcsEncrypt=newCryptoStream(mEncrypt,encryptor,CryptoStreamMode.Write)){using(StreamWriterswEncrypt=newStreamWriter(csEncrypt)){//将所有数据写入流swEncrypt.Write(plaintext);}转变。输出ToBase64String(mEncrypt.ToArray());}}最后{if(aesAlg!=null)aesAlg.Clear();}Console.WriteLine(outsrt);}这是解密方法:privatestringGetServiceAcctPW(){//声明RijndaelManaged对象//用于解密数据。RijndaelManagedaesAlg=null;//声明用于保存解密文本的字符串。字符串明文=空;try{//从共享密钥和盐生成密钥Rfc2898DeriveByteskey=newRfc2898DeriveBytes(sharedsecret,_salt);//创建用于解密的流。byte[]bytes=Convert.FromBase64String("EncryptedValueHere");using(MemoryStreammsDecrypt=newMemoryStream(bytes)){//使用指定的密钥和IV创建一个RijndaelManaged对象。aesAlg=newRijndaelManaged();aesAlg.Key=key.GetBytes(aesAlg.KeySize/8);//从加密流中获取初始化向量aesAlg.IV=ReadByteArray(msDecrypt);//创建一个解密器来执行流转换。ICryptoTransform解密器=aesAlg.CreateDecryptor(aesAlg.Key,aesAlg.IV);using(CryptoStreamcsDecrypt=newCryptoStream(msDecrypt,decryptor,CryptoStreamMode.Read)){using(StreamReadersrDecrypt=newStreamReader(csDecrypt))//从解密的//中读取解密的字节并将它们放入字符串中。明文=srDecrypt.ReadToEnd();}}}catch(Exceptione){Console.WriteLine("解密密码时出错");控制台.WriteLine(e.StackTrace);logger.WriteToLog(Logger.LogCodes.ERROR,"解密服务账户密码时出错");MessageBox.Show("尝试开始安装过程时发生错误请联系服务台以获得进一步帮助");}finally{//清除RijndaelManaged对象。如果(aesAlg!=null)aesAlg.Clear();}返回明文;这段代码工作正常,但是,我知道它不安全我的代码审查人员说他能够在一小时内用dotPeek破解它,因为它只是增加了一层混乱。在应用程序中存储这些凭据的最佳/正确方法是什么?加密密钥位于专用服务器上。密码将与要加密的ID一起发送到服务器,并返回用于数据库存储的加密密码。当需要密码时,用id向专用服务器发起请求,返回解密后的密码。密码永远不会保存到磁盘,密钥也永远不会在专用服务器上提供。专用服务器有点像穷人的HSM。这是加密,而不是散列。加密密钥是保密的,随机IV与专用服务器上的id一起保存。密钥不可用且与密码无关,因此没有比对加密密钥进行powershell攻击更好的攻击了,这基本上是一种强大的蛮力攻击。服务器需要非常安全,只需要两个因素登录,并且不能用于Internet。以上就是C#学习教程:在clickonce应用程序中安全地存储服务账户凭证。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收集,不代表侵权,请点击右边联系管理员删除。如需转载请注明出处:
