Java Web应用程序的SecureLogin

不,标题中没有缺少空格。 这与安全登录无关 ,而与安全顾问Egor Homakov开发的SecureLogin协议有关,该协议因在没有权限的情况下致力于掌握 Rails项目而闻名

SecureLogin协议非常有趣,因为它不依赖任何中央方(例如,Facebook和Twitter之类的OAuth提供程序),从而避免了OAuth的所有陷阱(霍马科夫经常批评)。 它也不是密码管理器。 它只是一个客户端软件,执行一些加密操作,以便向服务器证明它确实是正确的用户。 为此,关键在于两个部分:

  • 使用主密码生成私钥。 它使用密钥派生函数,该函数可确保产生的私钥具有足够的熵。 这样,使用相同的主密码和相同的电子邮件,您每次使用密码都会获得相同的私钥,因此也将获得相同的公钥。 您是唯一可以通过使用私钥签名消息来证明此公钥就是您的公钥的人。
  • 服务提供商(网站)通过在注册时将其存储在数据库中,然后在每次后续登录时进行查找来通过公钥来识别您

客户端部分最好由本机客户端执行-浏览器插件(Chrome浏览器可用)或特定于操作系统的应用程序(包括移动应用程序)。 这听起来可能很乏味,但实际上它既快速又容易,并且是一次性事件(并且比密码管理器容易)。

我必须承认–我喜欢它,因为一段时间以来我一直有一个类似的想法。 在我的“生物特征识别”演示文稿中 (我在这里讨论了使用仅生物特征识别方案的陷阱),我提出了(幻灯片23)一种使用生物特征(例如用手机扫描)+密码生成私钥的识别方案(使用键衍生功能)。 而且将来可以轻松将生物特征添加到SecureLogin。

当然,这还不是全部,因为一个问题尚未完全解决-撤销。 万一有人窃取了您的主密码(或者您怀疑它可能被盗了),您可能需要更改它,并将更改通知所有服务提供商,以便他们可以用新的旧密钥替换您的旧公共密钥。 这有两个含义-首先,您可能没有完整的注册站点列表,并且由于您可能已更改设备或使用了多个设备,因此有些网站可能永远都不知道您的密码更改。 存在提议的解决方案(第3点和第4点 ),但是它们不是协议固有的,而是依赖于集中式服务。 第二个问题是–如果攻击者首先更改您的密码该怎么办? 为避免这种情况,服务提供商可能应该依赖电子邮件验证,该电子邮件验证既不是协议的一部分,也不鼓励它。 但是,无论如何,您可能都必须这样做,以确保安全。

Homakov不仅定义了协议,还提供了本机客户端的实现,以便任何人都可以开始使用它。 因此,我决定将其添加到当前正在处理项目中登录页面在此处 )。 为此,我需要服务器验证的Java实现,并且由于不存在这种实现(目前仅提供ruby和node.js), 因此我自己实现了它 。 因此,如果要在Java Web应用程序中使用SecureLogin,则可以使用它而不是自己开发。 在实现它的过程中,我遇到了一些可能导致协议更改的小问题,因此我认为向后兼容性也应该以某种方式包含在协议中(通过版本控制)。

那么,代码看起来如何? 在客户端,您有一个按钮和一些JavaScript:

<!-- get the latest sdk.js from the GitHub repo of securelogin
   or include it from https://securelogin.pw/sdk.js -->
<script src="js/securelogin/sdk.js"></script>
....
<p class="slbutton" id="securelogin">⚡ SecureLogin</p>
$("#securelogin").click(function() {
  SecureLogin(function(sltoken){
	// TODO: consider adding csrf protection as in the demo applications
        // Note - pass as request body, not as param, as the token relies 
        // on url-encoding which some frameworks mess with
	$.post('/app/user/securelogin', sltoken, function(result) {
            if(result == 'ok') {
		 window.location = "/app/";
            } else {
                 $.notify("Login failed, try again later", "error");
            }
	});
  });
  return false;
});

单个按钮既可以用于登录也可以用于注册,或者,如果必须包含其他详细信息而不只是电子邮件,则可以使用单独的注册表单。 由于除了基于密码的登录名之外还添加了SecureLogin,因此保留了这两种形式。

在服务器上,您只需执行以下操作:

@RequestMapping(value = "/securelogin/register", method = RequestMethod.POST)
@ResponseBody
public String secureloginRegister(@RequestBody String token, HttpServletResponse response) {
    try {
        SecureLogin login = SecureLogin.verify(request.getSecureLoginToken(), Options.create(websiteRootUrl));
        UserDetails details = userService.getUserDetailsByEmail(login.getEmail());
        if (details == null || !login.getRawPublicKey().equals(details.getSecureLoginPublicKey())) {
            return "failure";
        }
        // sets the proper cookies to the response
        TokenAuthenticationService.addAuthentication(response, login.getEmail(), secure));
        return "ok";
    } catch (SecureLoginVerificationException e) {
        return "failure";
    }
}

这是spring-mvc,但可以是任何Web框架。 您也可以以某种方式将其合并到spring-security流程中。 我从不喜欢spring-security的复杂性,所以我手动完成了。 另外,您可以返回正确的状态代码,而不是字符串。 请注意,我正在通过电子邮件进行查找,然后才检查公共密钥(就像它是密码一样)。 如果在公钥列上有正确的索引,则可以采取其他方法。

我不建议您使用仅限SecureLogin的系统,因为该项目仍处于初期阶段,用户可能对此不太满意。 但是,当然,将其作为选项添加是个好主意。

翻译自: https://www.javacodegeeks.com/2017/09/securelogin-java-web-applications.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值