Java中实现可调用的最佳方法是什么,需要一段时间才能完成
作者:互联网
为了防止密码暴力破坏,并防止尝试检测有效用户名的计时攻击,我希望我的登录过程花费一定的时间,无论是否成功验证.简而言之,我总是希望我的登录过程可以说1000毫秒(假设结果需要一小部分时间),无论结果如何.在Java中实现这一目标的最佳方法是什么?这是我目前的想法:
class ConstantDuration<T> implements Callable<T> {
ConstantDuration(Callable<T> task,long duration) {
this.task = task;
this.duration = duration;
}
public T call() throws Exception {
long start = System.currentTimeMillis();
long elapsed = 0;
T result = null;
try {
result = task.call();
} finally {
elapsed = System.currentTimeMillis() - start;
}
if ( elapsed < duration ) {
Thread.sleep(duration-elapsed);
}
return result;
}
}
解决方法:
显然,你需要将sleep移动到finally块中,以便在task抛出异常(例如PasswordExpiredException?)时也会发生这种情况.
另一个问题是处理已经过去的情况>持续时间.你说永远不会发生,但你确定吗?如果您的数据库查询被锁定停止怎么办?假设您要在此类事件中拒绝身份验证,您可以执行以下操作:
ExecutorService exec = Executors.newFixedThreadPool(10);
<T> T doInConstantTime(Callable<T> task, long millis, T defaultResponse) {
Future<T> future = exec.submit(task);
Thread.sleep(millis);
if (future.isDone()) {
return future.get();
} else {
future.cancel(false); // or true?
return defaultResponse;
}
}
(当然,您需要添加适当的异常处理)
不过,我不确定这是否是防御暴力攻击的好方法.相反,我们在第三次连续失败的登录尝试后(在一段时间内或直到管理员解锁帐户)使用户的登录失效.提到你这样做的地方,没有人有理由强行密码.
标签:java,java-util-concurrent,brute-force 来源: https://codeday.me/bug/20190626/1292034.html