Securely send a Plain Text password?
我正在开发一个iOS应用程序,让用户填写密码。然后,使用post或get将密码发布到我的站点上的一个php页面。(它必须是纯文本,因为它在脚本中使用。)
除了https,还有什么方法可以保护密码吗?用obj-c加密然后用php解密?
注意:用户名没有发送…只有密码才会发布到服务器。
编辑:要澄清,大卫·斯特拉顿是正确的……我试图阻止公共场所的恶意嗅探器在发送到服务器时简单地读取明文密码。
- 简短回答:挑战回答。
- 我同意@fritvancampen的说法,您应该使用挑战响应。无论您选择什么,都不要使用get发送密码;始终使用post。GET可以被中间的任何实体(代理服务器等)缓存,在普通浏览器中,显示查询字符串并将其保存到历史记录中。
- 他说的是防止嗅探者发现它,如果他想知道替代HTTPS的方法。这个简短的回答"挑战回答"是如何应用的?(不是批评,只是希望有机会学习,希望你能更进一步地回答这个问题。)
- 尝试使用aes加密,并使用basic auth设置头。
- 在https之外,"安全地发送[纯文本]密码"的方法真的很简单。只需使用可用的工具。
- 这些工具是什么?
- @mihirsingh https;-)
挑战响应大纲
假设您具有单向哈希函数abc(实际上使用的是md5或sha1A cryptography strong hashing algorithm for php,请参见:password_hash)。
您在数据库中存储的密码是abc(password + salt)(单独存储salt)
服务器生成一个随机挑战challenge,并将其发送给客户机(与salt一起),并计算预期的响应:abc(challenge + abc(password + salt))。
然后客户端计算:abc(user_password + salt)并应用challenge得到发送到服务器的abc(challenge + abc(user_password + salt)),服务器可以很容易地验证其有效性。
这是安全的,因为:
- 密码从不以明文发送或以明文存储
- 每次发送的哈希值都会更改(减轻重播攻击)
有一些问题:
你怎么知道要送什么盐?嗯,我从未真正找到解决这个问题的方法,但是使用确定性算法将用户名转换为salt可以解决这个问题。如果算法不具有确定性,攻击者可能会发现哪个用户名存在,哪个不存在。但是,这需要您有一个用户名。另外,您也可以只使用一个静态的salt,但我对加密技术的了解还不足以评估该实现的质量。
- 这对于身份验证很好,而且是HTTP Digest身份验证所做的。由于XYZ的原因,这不适合将纯文本密码发送到服务器。
- 嘘,快一分钟。但是…还是个好建议。
- 感谢您的及时回复。这里的问题是密码从未存储在任何数据库中。密码被发送到脚本,脚本运行一些东西,并打印输出。
- 数据库不是必需的。你只需要三条信息:password(秘密),salt(公共知识,使你能够存储加密的password和challenge,每次都会有所不同。有了这个组合,你在密码上是安全的。
- @Fritvancampen假设不需要纯文本密码…在某些情况下可能需要它,例如传递到更好的统一模型之外的另一个服务。(如果一切都支持Kerberos,那就太好了,但是,唉,它不是。)
- @Mihirsingh,您可以将其存储在源代码的某个位置或右侧的文件中。如果您不需要复杂的用户系统,就不需要数据库。我的观点是,对于挑战响应,不需要数据库,而需要用户管理:可能。
- @在我看来,密码是亵渎神明的,永远不应该以明文形式存储。您只需传递散列密码和salt。假设两个系统上的盐化机制相似,这应该可以很好地工作。如果没有……无聊的
- 让我澄清一下…不仅密码从未存储在数据库中,而且也从未存储在服务器上的任何位置。脚本只检查密码,它不会将密码保存或存储在任何地方。
- 我知道加密和其他东西,所以告诉我…如果我在obj-c中使用aes加密,然后在php中解密,它会工作吗?
- 如果密码从未存储在任何地方,那么您如何知道它是正确的?。使用aes works,它使用不同的加密方法(public-private key,更类似于https)
- 这个解决方案的问题是,您只能验证用户是否知道密码。它不能保护请求的完整性,比如说中间人。
- 是的,https确实可以防止这种情况的发生(或者应该搜索"moxio marlinspike":p)。
- AES是一种对称算法。它在这里不起作用,公钥算法也不起作用,因为客户端没有任何根证书来验证公钥加密密钥的完整性。
- van campen先生,密码是否正确并不重要,没有用户基础。我只是分析字符串,而不是将其与用户数据库进行比较。
重新考虑不使用HTTPS。https是一种很好的防御多种攻击的方法。
通常没有理由传输密码。通过传输密码,您发送的是有价值的数据,而这些数据又是与之相关的额外风险。
通常您散列密码并提交散列。在服务器端,您可以比较哈希值,如果它们匹配,那就太好了。
显然,使用这种方法,散列值是很重要的,而且您必须防止重播攻击。您可以让服务器生成一个加密安全的一次性使用salt,将其传递给客户机,salt并散列密码,然后比较hashes服务器端。
您还需要防止对密码的反向散列攻击。例如,我有一个哈希,我可以将它与一组预先生成的哈希进行比较,以找到原始密码。
- 我给了一个+1作为开场白。其他部分是"meh"(好的"好建议"),但不属于这个问题。
- 我很乐意使用HTTPS,但我买不起证书。
- 如果您同时拥有客户机和服务器,则可以将自签名证书用于HTTPS。
- 如果你把答案缩小到第一行,我也会给你一个赞成票。剩下的太模糊了。
- 自签名的问题在于,您没有权限保证证书的正确性和有效性,而且这不是您可以让客户处理的事情,太不专业了。
- 典型的客户执行证书链有效于一个托管根。这是在你有第二次不信任的时候发生的。双方都有第三方信任,它们可以相互信任。自从你写信给顾客以来,你可以将数据送交自己的服务器,你可以将验证书的有效性忘记在根上。这是不理想的,因为袭击者可以进入你的验证和身份证,而你不能再回到验证中心。但是,对于你的使用,你自己签字的验证证书应该是好的。但是,我不是一个安全专家,这是免费的咨询意见。
- 但以同样的方式,用户永远不会知道证书是否有效,对吗?因为他们会看到IPHONE用户界面而我也没有计划从一家保安公司的某个海豹接口但我知道你在说什么Van Campen先生坦率地说,虽然大多数使用者不知道他们的密码是不安全的,如果我没有加密的话,但我只想作出努力来确保应用程序的安全。
- @Fritsvancampen agreed.我在下面加了一个长度。如果你有一个顾客,一个有效的托管人的费用应该在合同中订立,而且应该在合同中订立。
- @Mihirsingh that's not a reason not to employment proper security however.很容易通过Fiddler和http://requests运行iphone App。
- @Alan,Precisely.我知道吸尘器可以收集通过网络传递的所有信息,这就是为什么我要努力确保应用程序的安全。
你可以在设备上加密,在服务器上解密,但是如果通过网络传输的数据足够敏感,可以保证有那么多的工作,那么imho,我相信你最好只使用https。它是经过尝试的,真实的,并且已经建立起来了。
提醒你,它并不完美,而且已经有了针对旧版本的成功攻击,但是它比"滚动自己的"安全方法要好得多。
例如,假设您的密钥被编译了:如果您使用的是来自受信任的颁发机构的证书的HTTPS,那么您只需购买一个新的证书。hte deveice,如果它信任颁发机构,那么它将接受新的证书。如果按照自己的路线进行,那么不仅必须在Web服务器上更新密钥,还必须在客户机上更新密钥。我不可能想要那种头痛。
我不是说这个挑战是无法克服的。我是说,当工具已经存在时,可能不值得这样做。
- 即使你使用的是HTTPS,你也不应该在网上传递凭证。
- @Alan祝你好运,在这种情况下,在服务器上更改密码;-)(在这种情况下,最好在网上发送明文,让服务器进行哈希/管理。)
- 是的,很好,但总的来说,我喜欢采用纵深防御策略。如果您没有远程更改密码方案,请避免输入密码:)