切勿在程序中硬编码密码或加密密钥。
一般的经验法则是:您应该存储在用户计算机上的唯一凭据是与该用户关联的凭据,例如,使该用户能够登录到他/她的帐户的凭据。
您不应将开发人员凭据存储在用户的机器上。那不安全。
您必须假设存储在用户机器上的任何内容都为用户所知,或者用户可以轻松学习。(这是正确的假设:对应用程序二进制文件进行逆向工程以了解可能嵌入其中的任何密钥或秘密并不难。)
一旦你理解了这个一般原则,一切都会变得容易。基本上,然后您需要设计系统的其余部分和身份验证协议,以便客户端软件可以仅使用可以安全存储在客户端上的那些凭据进行身份验证。
示例 1. 假设您有一个 Facebook 应用程序 ID 和密钥,与您的应用程序相关联(即与您的开发人员帐户相关联)。您是否将应用程序 ID 和密钥嵌入到您交付给用户的桌面软件中?不!绝对不。您绝对不要这样做,因为这会让您的任何用户了解您的应用 ID 和密钥并提交他们自己的请求,这可能会损害您的声誉。
相反,你会找到另一种方式。例如,也许您设置了自己的服务器,该服务器具有应用程序 ID 和密钥,并负责向 Facebook 平台发出请求(受到适当的限制和速率限制)。然后,您的客户端连接到您的服务器。也许您通过让每个用户在您的服务器上设置他/她自己的用户帐户、将帐户凭据存储在客户端上并让客户端使用这些凭据对自己进行身份验证来验证每个客户端。
您可以通过让客户端应用程序在第一次执行时生成一个新的用户帐户(生成自己的登录凭据,将它们存储在本地,并将它们发送到服务器)来使用户完全不可见。客户端应用程序可以使用这些存储的凭据在将来进行连接(例如,通过 SSL),并在以后每次执行应用程序时自动登录。
请注意,存储在用户计算机上的唯一内容是允许登录该用户帐户的凭据——但没有任何内容允许登录其他人的帐户,也没有任何内容会暴露开发人员应用程序密钥。
示例 2。假设您编写的应用程序需要访问用户 Google 帐户中的数据。您是否提示他们输入 Google 用户名和密码并将其存储在应用程序本地存储中?你可以:那没关系,因为用户的凭据存储在用户的机器上。用户没有动力尝试破解自己的机器,因为他们已经知道自己的凭据。
更好的是:使用 OAuth 授权您的应用程序。这样,您的应用程序会将 OAuth 令牌存储在其应用程序本地存储中,从而允许您的应用程序访问用户的 Google 帐户。它还避免了将用户的 Google 密码(特别敏感)存储在应用程序的本地存储中,从而降低了泄露风险。
示例 3。假设您正在编写一个应用程序,该应用程序具有一个在所有用户之间共享的 MySQL 数据库后端。您是否使用 MySQL 数据库并将其嵌入到应用程序二进制文件中?不!您的任何用户都可以提取密码,然后直接访问您的 MySQL 数据库。
相反,您设置了一个提供必要功能的服务。客户端应用程序连接到服务,对自身进行身份验证,并将请求发送到服务。然后该服务可以在 MySQL 数据库上执行此请求。MySQL 密码安全地存储在服务器的机器上,并且永远无法在任何用户的机器上访问。服务器可以施加您想要的任何限制或访问控制。
这要求您的客户端应用程序能够对服务进行身份验证。一种方法是让客户端应用程序在首次运行时在服务上创建一个新帐户,生成随机身份验证凭据,并在以后每次自动登录服务。您可以使用带有随机密码的 SSL,或者更好的是,使用 SSL 之类的东西,为每个客户端使用唯一的客户端证书。
另一条规则是:您不要将凭据硬编码到程序中。如果您将凭据存储在用户的机器上,请将它们存储在某个私有位置:可能是配置文件或目录,最好是仅可由该特定应用程序或该特定用户读取的目录(不是世界可读的文件)。