2013-03-14 80 views
0

我有一点点的GAE应用,为我的Android应用程序在后台运行。 我在应用程序中有一个servlet,用于从数据存储中提取数据并将其发送给用户。 我不希望任何人能够使用这个servlet,所以我在应用中存储了一个私钥,并且为每个发送令牌的请求 - 私钥的哈希字符串和当前毫秒数,以及毫秒我在散列中使用。 服务器正在使用毫秒和私钥,并将其与令牌进行比较。如果进展顺利,服务器将存储毫秒数为HashSet,以便它不会再使用它。 (有人可以嗅探设备数据 - 并一次又一次地发送相同的毫秒和令牌)。App Engine中的servlet存储用于标记列表 - java的

起初,我在Servlet类,后来发现是错误举行静态字段,因为这个领域是不是依然存在,当实例被摧毁所有的数据都迷路。

我已阅读Memcache,但它不是最佳解决方案,因为据我所知,如果应用内存不足,或者即使存在服务器故障,Memcache中的数据也可能会被擦除。

我不希望使用数据存储,因为它真的会请求慢得多。

我想我不是谁面临的问题之首。 我该如何解决它?

回答

1

我用了一个相反的方法在我的应用程序之一:

每当一个新的客户端连接,我产生一组三个随机“挑战”服务器(如您毫秒),这是我在内存缓存中存储与上一分钟左右的到期时间。然后我将这些挑战传达给客户。对于客户端的每个请求,它需要使用以下3个挑战中的一个挑战(用私钥进行散列)。服务器然后删除使用的挑战,创建一个新的挑战并将其发送到客户端。这样,每个挑战都是一次性使用,我不必担心重播攻击。

这种方法有两点要注意:

  • 我之所以产生三个方面的挑战是允许在飞行并联多个请求。
  • 你做出挑战,就越有可能将是,这将是随机重复使用(允许回放攻击当时)的时间越长。
  • 如果memcache忘记我存储的挑战,那么应用程序的请求将失败。在失败的时候,我会回应一个“忘记所有其他挑战并使用这3个新的挑战:......”的命令。
  • 可以配合到客户端的IP地址或者一些其他类型的会话信息的挑战,使其更不可能有人能“砍”你。
  • 一般来说,让服务器生成验证的挑战或盐比向客户端提供灵活性要好。

,如果你想坚持使用时间戳,您可以使用另一种方法是使用的第一个请求交换,以确定时间您的服务器实例和客户端设备之间的偏移。然后,只接受带有“当前”时间戳的请求。为此,您需要确定可以获得时间偏移的不确定性,并将其用作截止时间戳以使其不是最新的。为防止在该截止时间段内发生重放攻击,您可能需要保存并禁止使用最后几个时间戳。这可以在您的实例中执行,因为AppEngine AFAIK将来自同一客户端的请求优先路由到同一个实例。然后,如果关闭一个实例并重新启动一个实例(即清除禁止缓存)需要的时间比您的“当前”-cutoff所用的时间更长,那么您不应该在重放攻击方面出现太多问题。

+0

谢谢您的详细解答。你面对挑战的方式是好的,但有一些额外的开销,我不确定我想添加到我的servlet中。我已经想到了你的另一种方式(有时间偏移),但是它留下了一些错误空间。我会接受你的回答,因为它给了我很多很好的信息,但我想我会坚持我的方式,只使用Memcache。谢谢! – Elad92 2013-03-15 09:01:17

相关问题