我有一个小程序可以检查几个文件夹中的旧文件,如果找到它们,它会向我发送一封电子邮件。一切正常,但我的电子邮件用户名和密码硬编码为:
SmtpServer.Credentials = new System.Net.NetworkCredential(
"uname@domain.com", "password");
一位朋友看了它并提到他会使用一个单独的类来使用静态方法重用电子邮件代码,但我不确定这是否有用(或如何实现)。我将开始使用Git / GitHub进行更改跟踪,并且我不希望将我的电子邮件硬编码到公共存储库中。
我知道smtp密码需要在某个地方以纯文本形式工作,但是我可以将其隐藏在我的代码之外并使用'使用'或其他一些选项,以便密码不存储在代码中?
使用Visual Studio Express 2012编写的程序
编辑1:应该说这只是一个控制台应用程序.exe文件,由Windows Scheduled Task调用以在远程服务器上进行某些文件夹监视。所以它在我的电脑上编译,但exe文件已保存并计划远程运行。
答案 0 :(得分:2)
对于诸如凭证(用户名和密码)之类的内容,通常最好将它们视为环境配置详细信息。也就是说,对于在任何给定环境中运行的应用程序的任何给定实例,它需要一些可配置的值来与邮件服务器进行交互:
环境配置通常包含在App.config
或Web.config
文件中。最简单的,你可能在配置文件中有这样的东西:
<appSettings>
<add key="SMTPUsername" value="uname@domain.com" />
<add key="SMTPPassword" value="password" />
</appSettings>
然后从代码中的配置中拉出它们,你会做这样的事情:
SmtpServer.Credentials = new System.Net.NetworkCredential(
System.Configuration.ConfigurationManager.AppSettings["SMTPUsername"],
System.Configuration.ConfigurationManager.AppSettings["SMTPPassword"]);
您可以在自定义配置类后面抽象这些设置,在配置中为空值时具有代码内默认值,对配置值执行各种错误检查等。但最终您将从中提取值配置文件。
然后可以将配置文件与公开可见的源代码分开。您需要包含在源代码中的配置文件,其中包含示例配置数据,因此使用该项目的人现在可以如何配置它。但是,您可以根据自己的需要保留未签入的本地配置,并将自定义配置文件部署到运行此应用程序的任何生产服务器。 (这就是配置文件的用途,存储同一应用程序实例之间不同的值。)
是否创建一个static
辅助方法来处理这个问题与隐藏这些值并不相关。你当然可以创造这样一种方法。如果你更喜欢你实例化的邮件程序对象,它不需要是静态的。 (也许是实现IDisposable
并使用它来内部处理SMTP对象资源的东西?真的可以根据需要获得创造性。)但是这种抽象本身并不会隐藏你的值,它只会将它们从一个类中移出源代码到另一个。您想完全从源代码中删除它们。
答案 1 :(得分:1)
将其移植到另一个DLL中将无助于隐藏此信息,为此,保护它的一种非常简单(但基本)的方法是首先将此用户信息移至您的应用配置,如
<appSettings>
<add key="user" value="user@mydomain.com" />
<add key="pwd" value="some password" />
</appSettings>
接下来你需要加密那个部分,如果它是一个网络应用程序,你可以运行下面的它,它将为你做的工作
aspnet_regiis -pe "WebConfigSectionName" -app "/WebAppName"
如果您的应用不是网络应用,那么您仍然可以对其加密,但您需要编写自己的加密例程,请参阅此MSDN article
最后在你的代码中,你应该能够从配置中读取数据,请注意,自从我上次这样做以来已经有一段时间了,所以试验了一下,但我认为你不需要任何特别的东西来阅读它在
string user = ConfigurationManager.AppSettings["user"];
string pwd = ConfigurationManager.AppSettings["pwd"];
警告:如果我没记错的话,运行加密的用户上下文和您的应用必须相同或可以访问相同的密钥,这意味着,如果您运行应用程序(或aspnet_regiis)将app config部分加密为“MySecurityUser”,然后运行app的帐户在需要读取加密部分时必须是“MySecurityUser”,它不能是“DaveUserId”(你将无法解密它)
答案 2 :(得分:0)
我可以在我的代码之外隐藏它并使用“使用”或其他选项调用它,以便密码不会存储在代码中吗?
当然,将信息存储在某个配置文件中。以编程方式读入文件。这里的问题当然是在许多情况下,单独的配置文件比编译代码中的更多暴露。
您可以加密信息,然后只将加密版本存储在配置文件中,但是您的配置文件或程序中的其他位置,您需要存储私钥以解密密码。你现在基本上提出了这个问题,因为你现在需要知道在哪里安全存储私钥。这使得这个问题实际上无法解决。您可以通过深入掩埋来获取更难找到的信息,或者要求某人跳过很多箍来获取信息,但是如果有一些方法可以让程序获得一些敏感信息,并且您拥有智能信息,确定的,有权访问该程序的恶意人员,然后他们最终将能够访问它。
答案 3 :(得分:0)
我确定有很多解决方案,但您可以做的一件事就是将您的电子邮件凭据存储在app.config中,然后像这样访问它们:
string email = ConfigurationManager.AppSettings["Email"];
string password = ConfigurationManager.AppSettings["Password"];
答案 4 :(得分:0)
您是否尝试将值添加到应用程序设置中?
您可以从“项目”菜单访问设置,查找&#34;属性...&#34 ;.这将打开属性页面,在左侧,您将看到&#34;设置&#34;。填写您的设置名称(例如&#34;密码&#34;)并输入(可能是字符串)。该值将保存在名为&#34; app.config&#34;的xml文件中。在你的项目中。编译完成后,您将该文件视为&#34; .exe.config&#34;。您可以在部署后修改该配置文件。
在代码中按名称访问该值:
SmtpServer.Credentials = new System.Net.NetworkCredential(
"uname@domain.com", Properties.Settings.Default.Password);
通过这种方式,您可以修改设置,而无需将机密信息提交到某个存储库。
答案 5 :(得分:0)
是否要求他们输入自己的电子邮件信息?
一种选择是将其放入注册表中:
http://www.codeproject.com/Articles/3389/Read-write-and-delete-from-registry-with-C
另一个选择是使用web.debug.config并且不要包含在存储库中:
How can I use Web.debug.config in the built-in visual studio debugger server?
答案 6 :(得分:0)
如果您在同一台PC上运行应用程序,可以使用ProtectedData。
首先加密您的用户名和密码(即在调试模式下,保存它然后在.cs文件中使用加密字符串)。
SmtpServer.Credentials = new System.Net.NetworkCredential( ProtectedData.Unprotect([encrypted]),ProtectedData.Unprotect([here encrypted data]));