我正在创建一个应用程序,其中,客户端向服务器发送请求,然后获取唯一的请求ID。稍后将使用此唯一请求ID在客户端再次与服务器进行交互时对其进行身份验证。
客户的请求有两种类型:
我的问题是如何生成ID?我正在使用Java和MySQL服务器数据库。如果我使用自动递增的数据库生成的id,那么客户端就很容易猜出id。另一个客户端可能通过猜测和滥用它们来恶意生成一些ID(客户端/服务器之间没有身份验证,除了ID:<)
如果我使用UUID或其他随机算法生成随机ID,那么我需要检查整个数据库(可能有数千条记录),真正检查并保证随机ID是否确实是唯一的?或者是否在数据库内快速检查id是否退出并且不会导致性能问题?
我应该采取什么措施?除了唯一ID?
之外,我是否需要在客户端和服务器之间使用更多安全措施进行身份验证?答案 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)