没有HTTPS的login,如何保护?

对于Web应用程序,当HTTPS不可用作安全措施时,是否仍然可以使login有点安全? 例如:

  • Tokenizelogin,使重复攻击困难?
  • 以某种方式encryption从HTML密码字段发送的密码?

特别是我使用CakePHP和AJAX POST调用触发身份validation(包括提供的用户名和密码)。

问题更新:

  • HTTPS不可用。 期。 如果你不喜欢这种情况,那么把它看作一个理论问题。
  • 没有明确的要求,你有任何HTTP,PHP和浏览器(cookies,JavaScript等)在现实生活中提供(没有神奇的RSA二进制文件,PGP插件)。
  • 问题是,什么是最好的,你可以做出这种情况,这比发送密码明文更好。 了解每个这样的解决scheme的缺点是一个加号。
  • 欢迎任何比普通密码更好的改进。 我们不瞄准100%l33tG0Dhx0r-proff解决scheme。 难以破解比复杂的破解更好,这比揭示密码的琐事更好。

HTTPS 维护网站和浏览器之间的安全连接至关重要 。 公共WiFinetworking使用户处于危险之中 ,如果使用得当, HTTPS是唯一可以保护用户帐户免受此漏洞攻击的工具 。

如果您的主机不支持HTTPS,那么即使您的服务器不支持SSL / TLS ,也可以使用像Cloudflare Universal SSL这样的服务来确保所有浏览器都使用HTTPS连接到您的站点。 Cloudflare和您的网站之间的连接仍然是不受保护的,但是这个Cloudflare服务旨在保护用户免受公共WiFinetworking上的威胁。 从渗透testing者的angular度来看,不提供HTTPS是非常值得怀疑的,如果您在提供stream量时没有提供基本的安全要求,那么您还缺less哪些其他安全要求? HTTPS证书可以通过Let's Encrypt或Start SSL免费获得,没有合法理由不支持HTTPS。

HTTPS至关重要,因为它不仅仅是“encryption密码”。 另一个重要angular色是它应该防止用户login到模拟真实服务器的恶意服务器。 仅使用一个系统来保护密码仍然违反了OWASP A9 – 传输层保护不足,因为您仍然会以明文forms传输会话证书,这是攻击者需要的( Firesheep )。

  1. 基于JavaScript的密码学不能用来构build安全的传输层 。

  2. “Tokenizelogin”:如果攻击者嗅探stream量,他们将拥有纯文本的用户名/密码,然后他们可以用这些新的凭据login。 (重播攻击)

  3. “以某种方式encryption传输的密码”:在用户login后,攻击者可以嗅探stream量以获取有效的会话ID (cookie),然后使用该密码代替login。如果整个会话受到SSL / TLS保护,则这不是问题。

还有其他更复杂的攻击会影响到这个系统和我们当前的SSL基础设施。 SSLStrip攻击更加详细。 我强烈build议观看Moxie Marlinspike的Blackhat 2009演讲 ,这将导致HTTP-Strict-Transport-Security标准 。

由于您无法在Web服务器上执行SSL,而且您也不是安全专家,因此请查找可以使用的现有安全身份validation服务,并让他们同时处理SSL和处理凭据的复杂性。

特别是,我build议你使用免费的第三方authentication服务,如OpenID 。 他们有PHP的库,其中一个用于CakePHP 。


编辑:(关于风险)

虽然使用第三方安全身份validation服务(使用HTTPS本身)可以在不使用HTTPS(在您的服务器上)的情况下减轻身份validation本身的问题,但并不能完全消除攻击的可能性。

最常见的两种攻击是重放攻击和会话劫持 ,攻击者可以在以后重新使用真正的login会话令牌,或者为自己的恶意目的使用有效的会话令牌。

通过让会话令牌到期,可以缓解重放攻击,最好使用随机数来防止会话重放,并降低会话劫持的风险。 使用随机数,如果成功劫持,合法会话会产生一个错误,因为随机数已经过期(已被使用),所以他们自己的会话不再有效。

如果在与服务器进行传输时不能使用HTTPS对会话令牌进行encryption,则不能完全防止诸如会话劫持中间人攻击之类的主动攻击。 在某些情况下这可能是可以接受的,例如非商业使用的小用户群的网站。

简而言之,没有SSL端点到端点的encryption,就不可能安全地做到这一点。

其中一个主要的原因是,你不能在浏览器中安全的encryption。 看到这个参考 – JavaScriptencryption被认为是有害的 。

此外,您无法确定证书的来源是否确实是您要与之通话的人。 这意味着没有SSL就没有办法确保没有人在中间的攻击 。

所以不,你不能这样做。

另外,甚至不要尝试。 获取SSL。 你可以得到免费的证书。 主持人通常会给你一个每月几个$$$的专用IP。 而且,如果你真的关心安全性,那么至less要使用一个专用IP地址的虚拟机。

甚至尝试这种做法,最好是默默无闻 ,而最糟糕的是没有。 SSL是一个解决的问题。 为什么不使用该解决scheme。 安全是不是可以猜测。 使用适当的技术。 不要试图发明自己的。 它不会工作…

正如您所build议的那样,每次创build页面时,您都可以生成唯一的标记。 同样的道理将需要与表单数据一起发回,不能重复使用。 如果你可以依靠它被用户启用,你也可以使用JavaScript来保证密码的安全。

但是,这个scheme仍然不安全。 攻击者仍然可以看到穿越线路的一切。 他们可以拦截令牌并在用户提交之前向您发送回复。 或者他们可以等待某人login,窃取该人的凭据(因为他们是通过电报发送的),并且稍后自行login请求。

底线 – 您需要使用HTTPS来保证网站的安全。

您可以使用Javascriptencryption密码并在服务器上解密。

我build议在服务器上生成一个RSA密钥对,并将公钥与定时盐一起发送到浏览器,然后使用Javascript中的公钥对密码进行encryption,并结合salt。

你可以在这里find一个JavaScript的RSA实现

您应该在authenticationcookie中包含IP地址和整个X- FORWARDED -FOR hedaer,以防止cookie在代理后面被盗用。

如果您处理敏感数据,您可以在Javascript中生成一个随机的AES密钥 ,然后将其与RSAencryption的密码一起发送到服务器。
然后,您可以使整个应用程序使用来自单个页面的encryption的AJAX请求,而不是使用auth cookie。

请注意,无法防止没有SSL的活跃中间人攻击。 一个积极的攻击者可以完全用自己的代理取代你的网站,而且没有任何办法来防止这种攻击。 (因为不可能有任何已知的好代码)

您可以使用大多数浏览器支持的HTTP摘要式身份validation,并且不会通过线路清楚地发送密码。

缺点是通过浏览器显示丑陋的login框。 如果您坚持使用表单,那么您可以在表单authentication中实现与HTTP摘要完全相同的协议:发送包含领域和挑战的隐藏字段,并让客户端在JavaScript中添加现时并计算摘要。 这样你就可以使用一个众所周知的,经过validation的繁殖协议,而不是自己动手。

HTTP摘要只需要散列操作。

怎么样HTTP摘要authentication ? 它在发送给服务器之前,通过MD5哈希用户名,密码和一个随机数(等等)来提供安全性。 MD5不是很安全,但是这对于简单的HTTP安全来说是一个很好的方法。

当然,这并不能防止黑客更改信息,但它会保护您的密码。

HTTPS有许多用例,其中大部分用于防御中间人(Man-in-the-the-middle)攻击。 任何有黑客心态的人都会不寒而栗地告诉你,除了已经build立起来的方式之外别无他法。 事实是,仅仅因为你使用TLS(现代HTTPS使用的标准),并不意味着你使用得很好。 另外,仅仅使用TLS并不能防止有人利用已知的弱点。 就像您可能正在寻找创造性的方式来保护您的数据一样,有些人正在寻找创造性的方式来利用您的安全措施。

那么该怎么办?

首先,如果您要放弃TLS,了解它的工作原理是很有帮助的。 这完全是关于握手。

一旦客户端和服务器同意使用TLS,他们就通过握手过程协商一个有状态的连接[7]。 在握手过程中,客户端和服务器就用于build立连接安全性的各种参数达成一致:

  • 当客户端连接到请求安全连接的启用TLS的服务器并提供支持的密码套件(密码和散列函数)的列表时,握手开始。
  • 从这个列表中,服务器select一个它也支持的密码和散列函数,并通知客户这个决定。
  • 服务器以数字证书的forms发回其标识[矛盾]证书通常包含服务器名称,可信authentication中心(CA)和服务器的公共encryption密钥。
  • 客户端可以联系发布证书的服务器(如上所述的可信CA)并在继续之前确authentication书的有效性。
  • 为了生成用于安全连接的会话密钥,客户端使用服务器的公钥对随机数进行encryption,并将结果发送给服务器。 只有服务器应该能够用它的私钥解密它。
  • 从随机数开始,双方产生encryption和解密的密钥材料[矛盾]握手结束,开始安全连接,使用密钥材料encryption和解密,直到连接closures。

如果以上任一步骤失败,则TLS握手失败,并且不会创build连接。

来源: 维基百科

那么,这可能吗? 是。 我被教导任何事情都是可能的。 这可能是昂贵的,但总是可能的。

我想充分披露,我不是一个安全专业,只是一个发烧友。 我不build议将其用于生产级别的项目或除了您自己的教诲以外的任何项目。 你应该明确检查这个SOpost ,它提供了一个很好的解释,在设置自己的安全协议的障碍。

但是,如果你想继续前进,下面是一些想到的想法。 无论您在这个项目中使用哪个指导,这些都是现实。

  • 所有主要的现代浏览器都支持HTTPS。 即使在这种情况下,HTTPS加载时间比普通的HTTP要慢。 如果没有大规模生产,很可能你的替代实施将成为安全的一小部分,而速度明显较慢。 除非您使用浏览器function,否则这将成为本地实现的一个缺点,这将使我们回到使用TLS(这是现代HTTPS所使用的function)。

  • 如果您在浏览器端使用JavaScript以不可预知的方式encryption密码,而浏览器端没有使用TLS,那么MiTM攻击将非常困难,请不要在那里rest。 您还应该保护来回发送的数据。 否则,被encryption的密码确实是无关紧要的。 当然,攻击者可能不知道bobsmith109的密码,但他不需要它,因为他可以嗅探networking上的每一个活动。 他知道bobsmith109login的次数,大概可以追溯他的IP以及其他任何你敏感的数据。

  • 不pipe你采取什么安全措施,都有深度的安全。 所以你可以做的一件事是确保你在数据库中encryption你的数据,同时也需要强密码。

我重申,我不是一个安全专业人员, 强烈地劝阻你,这是为了满足你的好奇心。 如果没有一个非常庞大的安全专业人员为项目贡献数年(如果不是数十年的话),这是SSL / TLS可以夸耀的,那么在天文学上就不太可能创build一个可行的TLS替代品。 也就是说,如果你select了前进的话,一个好的起点是看看上面的握手模型,看看如何在没有TLS的情况下实现这个版本。

我会不愿意在我的post中分享使用HTTPS的大多数现实障碍正在被积极抵制。 最大的成本之一 – 非常接近成为一个非问题。 一个免费的证书颁发机构将在2015年第二季度推出,其中包括Mozilla和Akamai等一些大型的枪支。 这是一篇文章 。

看看“安全远程密码协议”

而不是自己来制定它,让我引用他们的网站:

安全远程密码协议执行安全的远程人身临时密码validation,抵御被动和主动networking攻击。

和:

该协议将零知识certificate技术与非对称密钥交换协议结合在一起,并且提供了相对于较强扩展方法(诸如增强型EKE或B-SPEKE)抵抗被盗检验器攻击的显着改进的性能。

尽pipe斯坦福大学没有提供PHP和JavaScript本身的实现,但它们链接到一些第三方实现。

其中一个链接导致“Clipperz” ,这是一个在线密码pipe理器。 它也可以在GitHub上作为社区版本使用。 他们在那里托pipe他们的“javascript-crypto-library” ,它实现了协议和“密码pipe理器”本身,后者包含用PHP和Python编写的后端。

我不能说提取代码的相关部分是多么困难,但也许你可以重用他们的实现(它是根据AGPL许可的)。

编辑2014/10/24:

维基百科关于SRP的文章列举了更多的实现。 相关的PHP / JS:

  • srp-client(JS)
  • srp-6a-demo(PHP / JS)

您可以尝试使用公钥encryption(也许是GPG)并利用浏览器caching来复制它。

这不是一件安全的事情,即使只是把SSL放在一个复杂的攻击者身上也是不够的,你需要使用HSTS,公钥pipe理等等来考虑今天的安全网站。

其余的答案只是一个思考的食物。

  1. 创build一个公私密钥对。 保持私人安全。
  2. 创build一个包含公钥和encrypt函数的js文件,find一个安全的encryptionalgorithm。 这个函数应该使用额外的时间戳来encryption给定的string(序列化forms),以避免复制攻击。
  3. 使用Cache-Control:public, max-age=31536000服务此文件Cache-Control:public, max-age=31536000 HTTP标头。 我们试图减轻攻击者何时试图replace脚本。 该文件将始终从浏览器caching中提供。
  4. 使用encryptfunction通过Javascript发送所有表单。 用与上面相同的标题服务这些。
  5. 在服务器端, decrypt数据,检查时间戳,如果它仍然有效。 你的事情,如果不是,丢弃它。
  6. 创build一个cookie标记,只能在很短的时间内使用一次。 如果攻击者抓到一个cookie,他就没有太多的时间去做东西了。 但是,如果攻击者速度够快,那么他可能会将原始用户logging下来。
  7. 更改每个响应的cookie。 但是,当用户一次发送多个请求,然后以相反的顺序到达时,你会做什么? 哪个cookie有效? 这会以虚假的安全感为代价,产生大量的问题。

任何监听器将无法使用来回的数据,并且在caching到期/用户清除caching之前,他们将无法更改/注入现有的 JS文件。 但是,任何复杂的攻击者都可以replace整个HTML文件,这将丢弃我刚刚提到的所有安全性测量。 如果你至less可以通过HTTPS提供这个文件/表单,那么你可能会放弃它,把它们放在Github页面上或其他任何地方。 但是,如果您将该文件放在其他某个域中,则需要为接收域设置CORS以使其正常工作。

另一个尝试

一次性密码发送到电子邮件。

  1. 用户填写他们的电子邮件,点击一个链接,然后发送一个链接到他们的电子邮件与令牌,使他们login。
  2. 用户点击链接
  3. 服务器检查令牌,将用户login。
  4. 像前面的例子一样滚动cookies。

总而言之,无论你做什么,都是不安全的 。 鉴于一个快速,复杂的攻击者,没有任何阻碍。

获取SSL,如果基础设施不支持,请更改它。 如果您的经理不相信SSL,请说服他/她。 不要造成错误的安全感。 根据您的位置保护您的用户数据,您在法律上被要求保护您的用户的数据。

那么让我们来谈谈如何使用SSL来保护网站安全。

没有HTTPS的login,如何保护?

由于您的服务器和您的客户端之间没有安全通道:

  • 因为没有安全的渠道,任何人都可以窥探你的stream量。
  • 因为任何人都可以窥探这个stream量,所以你是面对MITM攻击的。
  • 因为你对MITM攻击是开放的,所以不能保证你的客户会看到一个合法的页面。
  • 因为页面是不合法的,你的页面实际上没有被服务(中间的人正在服务页面),所有使用服务器端的技巧都是无用的。

你能做什么? Theorically?

  • 客户端和服务器端都需要使用encryption技术来减lesssnooping / MITM。
  • 假设你不能握手,
  • 假设你的客户已经拥有了你的钥匙,并知道如何说服你的服务器一样的胡言乱语。
  • 如何通过HTTP的一些SSL,但包装在一些乱码base64编码的消息?

但是等等…既然你说没有神奇的二进制文件或插件,甚至没有RSA,我不知道这是否可能,除了(一些潜在的非常弱)的内部encryption。

在尝试回答之前,我想提一下,这里的其他答案都是关于HTTPS / STS的。 HTTPS是坚定的,可信的,也许是你最好的select – 我相信你已经厌倦了听到它。 现在,我不是安全专家,但是这个问题是我想到的,而且我碰巧创造了一个方法。 我从来没有用过它,我要求所有人尽可能地去打洞。 它只能防止中间人攻击。

这个想法是在没有握手的情况下实现共享的秘密部分,即使这意味着在另一个安全的服务(如电子邮件,假设他们使用TLS来读取它)上捎带。

第1部分:安装

  1. 也许select一个对称密码,Rijndael。

  2. select哈希algorithm,SHA256 / 512是我的最爱。

  3. 创build一个大的盐,一些随机的数据,理想情况下有点强壮。 512字节也许。 我们称之为GSALT。 (将其视为一个名为GSALT的variables)。 这将是一个全球盐。 可能是好的configuration文件材料。

  4. 在你的数据库中,用户数据应该包含一个用户名字段,一个userhash字段,一个密码字段,一个salt字段,一个key字段和keyhash字段(加上你想要的任何东西,我只覆盖相关的字段)。 我将解释每个字段应包含的内容:

    • 用户名:用户在注册时select的实际用户名。
    • salt:随机生成的string,长度至less为32个字符。 我喜欢让他们64.这可能是浪费,但我是偏执狂。 我们称之为LSALT。
    • 密码:GSALT +实际密码+ LSALT的散列。 依次排列。
    • userhash:应该包含GSALT +用户名的散列。 索引的速度。
    • 键:应该包含一个随机string(基本上是另一个盐,但是我们将半公开使用)
    • keyhash:包含GSALT +实际密码+密钥的散列。 依次排列。

第2部分:注册新用户

  1. 在registry单中,提示input用户名,电子邮件,但没有密码。
  2. 一旦validation和接受,生成一个密码服务器端,并将其发送到他们的电子邮件。
  3. 在您的数据库中,生成第一步中提到的不同值(userhash,password,salt,key,keyhash等)

第3部分:身份validation

  1. 用login名包含全局salt。
  2. 在login尝试中:
    • 通过散列GSALT +用户名来创builduserhash
    • 通过散列GSALT +密码创build一个passhash
    • 发送userhash并通过传送到服务器
  3. 在接收这些的服务器上:
    • find匹配userhash的用户logging
    • 从该logging获取密码和盐值,并通过散列密码+用户盐(LSALT)validation此用户名是否具有正确的密码。
    • 如果匹配,则用户通过身份validation。 产生一个随机数(一个随机数字或一个体面大小的string,使其不能被猜到)
    • 使用keyhash值作为encryption密钥对nonce进行encryption,并在其有效负载中生成一个具有nonce的标记。 此令牌应使用单独的服务器端唯一密钥(请参阅JWTscheme)。
    • 发送密钥,encryption的随机数和令牌。
  4. 客户端收到密钥,encryption的随机数和令牌。
  5. 客户端哈希GSALT +实际密码+密钥来产生解密现时所需的encryption密钥。
  6. 丢弃除客户端上的随机数和令牌之外的所有其他值。
  7. 对于每个客户端请求,使用nonce作为关键字来encryption内容。 用令牌发送encryption内容。 不要encryption令牌。 只需将令牌作为请求数据的单独值发送即可。
  8. 服务器收到encryption的请求和令牌,解密令牌,然后使用随机数解密请求的内容。
  9. 服务器生成一个响应,使用随机数对它进行encryption,并将其发送…来回/等等

问题

  1. 双方的计算都很昂贵。
  2. 它不能抵御很多其他的攻击,并且可能更容易受到旁道攻击。
  3. 全球盐基本上是永远的交易:/
  4. 我不是安全专家,这可能不是密封的。 “不要推出自己的encryptionscheme”是有原因的。
  5. 一个足够专门的黑客可以build立一个彩虹桌,或者蛮力检查你的哈希密码。
  6. 这是作弊,因为我们使用电子邮件来规避一个麻烦的地区。

不过,这是一个有趣的思想实验! 我希望它可以帮助某人(特别是如果这意味着推动他们使用HTTPS)

我所见过的最安全的HTTP连接最好的解决scheme是使用md5sum(或其他散列)的Javascript实现来避免以明文forms传输密码。 您可以在Javascript中创build一个窗体onsubmit处理程序,用原始值的散列replace密码字段。 这为不安全的连接增加了适度的安全性,但是依靠浏览器中运行的Javascript来正常工作。

答案是短的,如果你真的关心安全,你总是有不同级别的官僚选项。

绝对安全不存在。 头号瑕疵总是在客户端,与木马键盘logging器 。 SSL没有帮助。

1) 令牌生成器 :银行使用它们,然后暴雪使用。 它可以是一个设备或应用程序。 那么..这很贵。

2) SMS引脚 。 有趣而又实惠的解决 市场上有很多优惠的价格,每个人都有可以接收的电话。

3)如果你必须使用HTTP,你可以强制第三方oauth服务,如谷歌Facebook 。 没有令牌生成器,这是最好的。

我想你关心密码到服务器的安全传输? 我的答案是:不要传输密码到服务器:)

事实上,您可能不会传输任何从浏览器(用户)到服务器的身份validation用户,因为正在窥探httpstream量的攻击者也将能够重新传输数据并进行身份validation。

提案:

明显的解决scheme是使用源自服务器的单向,一次性事务validation; 像一个只能使用一次的交易号码。 最终,您仍需要一个安全通道才能将用户的交易号码列表同步。

你可以使用google authenticator ,但是你需要一个安全的通道来设置参数。 如果你认为电子邮件是安全的,这将是一个方法。

我的系统上有同样的问题。 我已经采取了一些步骤来尝试提高安全性,同时又不会由于复杂的机制而影响用户体验。 我注意到,绝大多数用户使用相同的浏览器(但不一定是相同的IP地址),或从几个浏览器(例如桌面或移动设备)login同一台机器。 我决定我可以用它来识别一个模式。

1)在注册过程中,用户需要拥有强大的密码(防止字典攻击),安全问题/答案和标准的电子邮件validation(作为真人的certificate)

2)在login过程中,5次login尝试失败(不是以前)后,将显示一个validation码以防止暴力攻击。

3)最后,我创build了一个包含用户操作系统,浏览器(一般不是版本)和语言的成功login后的用户代理string部分的散列 – 形成一种二级密码。 如果下次login时useragent哈希值显着不同,则会要求用户回答安全问题。 然后,如果回答满意,新的UAstring将被散列并添加到他们的“安全机器”列表中,这样他们就不会再被询问。 这与Steam游戏系统采用的机制类似。

这已经在大约700个用户中使用了一年多,并且还有防止“login共享”的额外好处 – 多个用户为了方便而使用相同的凭证的问题!

试试这个:在login页面的每个请求上,发送一个随机数和一个时间戳。 在发布到服务器时,发送以下四个详细信息:

用户名,密码和明文的时间戳。 然后用分隔符(例如:换行符)连接上述内容,并使用用户密码作为encryption链接块密码模式进行encryption。

在服务器端使用用户名来查找密码并validationencryption的string。

由于密码永远不会被清楚地传送,所以它是安全的,并且可以使用时间戳来避免重新提交相同的数据。

为了避免通过中间人攻击获取会话密钥来劫持会话,密码或密码的哈希值可以由客户端上的应用存储在内存中,并用于生成唯一的会话密钥供服务器validation。

看看OAuth 1.0也不是一个坏主意。

如果您不能使用HTTPS,或者您不想使用HTTPS,请考虑使用jCryption 。 jCryption为通过HTTP请求(POST,GET等)发送的数据提供encryption。

您可以在这里testing技术: http : //www.jcryption.org/#examples

如果你使用的是Firebug,你会看到所有的数据都被encryption了。

它有jQuery库来encryption前端数据和一个PHP库来解密后端的数据。

使用散列机制来存储密码,并且总是比较散列的密码,甚至没有人知道真正的密码。 这是非常简单的,但它是有效的。但是,没有什么是完全安全的,有一些办法打破scurity层。

没有一个trusted third party 很难确保沟通的安全,但是,对于你来说有一些安全的技巧:

不要将用户的敏感信息暴露给公共networking。

每个敏感信息都应该散列好或公钥encryption。 注意:如果select用公钥encryption用户敏感信息,请确保用户validation公钥。 例如,您可以通过短信甚至自动呼叫向用户发送某种公钥指纹。

login成功后生成SHARED SECRET

在安全login事务之后,应该生成共享密钥。 生成过程可以参考SSL Handshake注意:共享密钥一旦生成,就必须再运行。 它唯一的function是在ServerBroswer之间encryption/解密数据

那里应该是一个两步validation,以避免重复的攻击

愿这些技巧能帮助你