为客户端服务器身份验证生成唯一ID

时间:2012-05-21 11:23:01

标签: java mysql uniqueidentifier

我正在创建一个应用程序,其中,客户端向服务器发送请求,然后获取唯一的请求ID。稍后将使用此唯一请求ID在客户端再次与服务器进行交互时对其进行身份验证。

客户的请求有两种类型:

  1. 新请求,其中没有现有ID和来自的响应 server生成并返回一个id。
  2. 带有id的现有请求。然后,服务器处理客户端 要求提供身份证明。
  3. 我的问题是如何生成ID?我正在使用Java和MySQL服务器数据库。如果我使用自动递增的数据库生成的id,那么客户端就很容易猜出id。另一个客户端可能通过猜测和滥用它们来恶意生成一些ID(客户端/服务器之间没有身份验证,除了ID:<)

    如果我使用UUID或其他随机算法生成随机ID,那么我需要检查整个数据库(可能有数千条记录),真正检查并保证随机ID是否确实是唯一的?或者是否在数据库内快速检查id是否退出并且不会导致性能问题?

    我应该采取什么措施?除了唯一ID?

    之外,我是否需要在客户端和服务器之间使用更多安全措施进行身份验证?

6 个答案:

答案 0 :(得分:2)

为每个会话创建一个编码且唯一的密钥,这些密钥将使用您对该用户的唯一数据创建,例如他的电子邮件,当前时间等。

String yourString = "user@email.com"+"timestamp"; 
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);

将为每个请求生成唯一ID,将它们存储在数据库中包含到期时间戳,用户ID和密钥的表中。在每个请求上,更新"到期"时间,如果它仍然有效,或者如果它过期或无效则返回错误。

我使用的有效密钥表类似于:

userId(int)
key(varchar(32))
expiry(int)

然后,如果您想查看某个用户是否打开了有效的会话,您只需检查userId的该表,并确保它是一个独特的列,以避免存储历史记录以前的会议。

答案 1 :(得分:2)

您可以使用Java的UUID。 类似的东西:

UUID uniqueKey = UUID.randomUUID();

如果你不想使用它,你可以使用时间,因为它总是在变化,如果你想确定的话,可以添加一个随机数。

答案 2 :(得分:2)

使用java.util.UUID.randomUUID();,您可以生成加密安全的随机UUID。

由于UUID长度为128位,因此碰撞的可能性微不足道,但如果您确实想检查冲突,可以通过在数据库中存储活动UUID并在生成后检查重复项来实现。

答案 3 :(得分:2)

如果您使用 Spring Framework ,您可能会发现另一个有用的UUID实现org.springframework.util.AlternativeJdkIdGenerator

IdGenerator generator = new AlternativeJdkIdGenerator();
UUID uuid = generator.generateId();

哪个来自文档:

  

使用{@link SecureRandom}作为首字母的{@link IdGenerator}   之后种子和* {@link Random},而不是调用{@link   UUID#randomUUID()}每隔*时间为{@link   org.springframework.util.JdkIdGenerator JdkIdGenerator}。 * 这个   在安全的随机ID和性能之间提供了更好的平衡。

答案 4 :(得分:1)

如果您想在MySQL端生成它,我认为这样做会很好

md5(concat(UNIX_TIMESTAMP(),<user_id>)) 

如果该字段已编入索引,则查询不会花费很长时间。

答案 5 :(得分:0)

  1. 使用UUID生成几乎始终唯一的基本ID。
  2. 散列基本ID,使客户难以猜测和欺骗。
  3. 使用具有唯一约束的列将散列ID存储在数据库中。
  4. 在极少数情况下违反了唯一约束,请重复上述步骤。