0
votes

I'm looking to make a basic invite codes authentication system that generates a 32 bit checksum but is shuffled each time.

I want to allow a mass of people into a system, lets say 500k people, I want to generate an invite code to be sent via email or snail mail. I DON'T want to generate a bunch of codes to store in a table for comparison, so the code will need to appear random but actually have the same checksum.

Is there a jQuery plugin that could reorder a string so I can do this?


Generate code > e.g. 123456 (but random order) Signup > enter code > 123456 : Does 1+2+3+4+5+6 = 16?

1
What prevents someone who didn't get an invitation from guessing invitation codes until he gets in?ntoskrnl
This is for early invites, its not a security layer. Just want to validate early users with a code.chris
I don't understand. Validation is useless if it's not secure. Anybody could come up with valid codes.ntoskrnl
I've updated the question to clarify my position.chris

1 Answers

1
votes

I want to allow a mass of people into a system, lets say 500k people, I want to generate an invite code to be sent via email or snail mail. I DON'T want to generate a bunch of codes to store in a table for comparison, so the code will need to appear random but actually have the same checksum.

You're going to want to use something like SipHash to create a keyed checksum.

const crypto = require("crypto");
const siphash = require("siphash");

const key = siphash.string16_to_key("This is the key!");

function createInvite(message, key) {
    return siphash.hash_hex(key, message) + message;
}

function inviteIsValid(combined, key) {
    let checksum = combined.slice(0, 16);
    let message = combined.slice(16);
    let recalc = siphash.hash_hex(message, key);
    return constantTimeEquals(recalc, checksum);
}

function constantTimeEquals(a, b) {
    if (a.length !== b.length) {
        return false;
    }
    let diff = 0;
    for (let i = 0; diff < a.length; i++) {
        diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
    }
    return diff === 0;
}

SipHash is short (so it's not collision resistant), but it should be secure for your use-case as long as your key is secret.

Usage:

let invite = createInvite('12345678', key);
if (inviteIsValid(invite, key)) {
    // permit
}

If you want to protect against online attacks, you'll want something more secure (i.e. HMAC-SHA256).