I'm working for a company that is generating gift card codes which can be used to pay for goods on online stores.
I'm wondering what the most secure way of generating these gift card codes are. The length needs to be 16 characters (though that is negotiable) and can be alphanumeric (though numeric would be more customer friendly).
From what I can see, the most secure way to do this is generate a gift card code of a specific length with the following Java code:
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static SecureRandom rnd = new SecureRandom();
String randomString( int len ){
StringBuilder sb = new StringBuilder( len );
for( int i = 0; i < len; i++ )
sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
return sb.toString();
}
This is taken from the SO answer here. I removed the lowercase letters from the string to make it more user friendly. So this produces 36 ^ 16 combinations. Numeric alone would be 10 ^ 16 combinations. I believe numeric alone would be enough but it's often stressed that, given the increasing prevalence of gift card fraud, the string should be alphanumeric.
So that's question one: numeric or alphanumeric?
When users use the gift cards on an online store to pay for goods, a call is made to our API which returns the balance and currency for that gift card. Given that the gift card codes are entered on 3rd party servers, these gift cards are now available to people with access to those servers. This is obviously a problem in the case where there is still a balance left after a user has partially redeemed one.
One option would be to, when the call to our API is made (with the gift card code) to get the balance, we return and save on their store a random string which can only be used by the online store when they are billing us - we will match that with the gift card code on our system. The problem with that is presumably the gift card code the user enters on checkout gets logged somewhere in their logs, and is accessible to anyone with access to those logs.
Another option is that we refresh the gift card code after it is partially redeemed. So the user essentially gets issued with a new gift card code for the balance and the previous one is cancelled. This is probably the most secure, but not that user friendly.
So that's the second question: how do we secure gift card codes that are only partially redeemed and still have value left on them?
The numbers are typically generated by algorithms and stored in a database. When a new number is generated, an encrypted salted hash is stored in the database. When you redeem the card the system check the database and verifies that it is the correct number / pin / value amount.
Yes, the gift card generator is completely free to use and you can create as many free gift card codes as you want.
Store your gift cards securely.Keep physical cards in a wallet, purse, or other secure place. If the card has a PIN covered by scratch-off material, leave the scratch-off material in place until the PIN is required.
Fraudsters can virtually print money for themselves by hacking into a company gift card database to steal card numbers and activation codes. This can be done via brute force hacking methods, malware, or using phishing or social engineering attacks against company employees.
So the problem you are facing is an interesting problem. I read @Therac's solution to the problem and I would have to agree with him that you would end up creating a protocol similar to a crypto-currency. I also agree with all his cryptographic suggestions.
I will not repeat @Therac's solution, however, I will see if I can help by explaining some ideas from crypto-currencies. I will not go into much technical detail, but at a superficial level and you can judge for yourself if the idea holds merit for your use case.
So the data structure that most cryptocurrencies use is a Merkle hash tree. The idea is that they keep it as an append only log of transactions to verify previous transactions and that they are not being double spent.
So there are two types of transactions.
Create transactions are only valid if it is signed by your company. Thus you would store the amount you gave, the user's public address (Potentially his account number) and his gift card code.
The second kind of transaction would then be SpendGiftCode. This requires the person's gift card code and would require him to also sign the transaction to validate that the transaction is coming from him.
SpendGiftCode then consumes the gift card code completely (destroys the gift card code and stores that it's been used) and does one of two things:
giftcardcode
is generated to the public address of the person he is paying to (which is the other parties account number).giftcardcodes
are generated. One which is of $10 is sent to the other party and a new giftcardcode
of the remaining amount is sent back to his account.This would require account creation for your users and vendors but can help mitigate issues such as double spending and tracking. Since it is an append only log, you will be able to follow the trail of transactions every vendor and user makes. The merkle hash tree allows for optimizations in the log keeping.
Of course, there are several layers of technical difficulties I did not dive into and there are of course some plot holes in my explanation since I tried to provide a broad conceptual idea. Feel free to edit wherever you may see a mistake. Hope this was of some help,
Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With