Short Description
I am wondering if there is a way to store an alternative of the full credit card number securely, which the card number is not required to be retrieved from the alternative.
Long Description
My goal here is to somehow store an alternative of the customers' full credit card number in database thus we could identify the same customer on their next purchase. However it should be a huge security problem if we hash/encrypt the full number in database. So I am referring the idea of one-time pad cryptography where used the CC as the private key (Key) and the key will be used to encrypt a random string which will follow a pattern (Plain Text). Thus the Key
will not be stored in the database, and there are millions of possibility of the Plain Text
.
Exact Flow of the Initial Idea
Testing card number: 4539112781735373 (source: http://www.getcreditcardnumbers.com/)
A) Encrypt full credit card number by bcrypt with cost 14 ($2y$14$g161t43Dcu7beXbIn2a55.LvH.Cpn7pwu05MPCz1PbAzbFEr0SqZS
)
B) Convert the bcrypt output to bytes (00100100 00110010 01111001 00100100 00110001 00110100 00100100 01100111 00110001 00110110 00110001 01110100 00110100 00110011 01000100 01100011 01110101 00110111 01100010 01100101 01011000 01100010 01001001 01101110 00110010 01100001 00110101 00110101 00101110 01001100 01110110 01001000 00101110 01000011 01110000 01101110 00110111 01110000 01110111 01110101 00110000 00110101 01001101 01010000 01000011 01111010 00110001 01010000 01100010 01000001 01111010 01100010 01000110 01000101 01110010 00110000 01010011 01110001 01011010 01010011
)
C) Generate 6 random 10-digits numbers follow a pattern as the plain text (the pattern should be simple enough to leave more open possibilities and complicate enough for to be identifiable, let's say they all can be divided by 2 and 7) (1410065398 1410065384 1410065370 1410065356 1410065328 1410065342
) and convert the numbers to bytes (00110001 00110100 00110001 00110000 00110000 00110110 00110101 00110011 00111001 00111000 00110001 00110100 00110001 00110000 00110000 00110110 00110101 00110011 00111000 00110100 00110001 00110100 00110001 00110000 00110000 00110110 00110101 00110011 00110111 00110000 00110001 00110100 00110001 00110000 00110000 00110110 00110101 00110011 00110101 00110110 00110001 00110100 00110001 00110000 00110000 00110110 00110101 00110011 00110010 00111000 00110001 00110100 00110001 00110000 00110000 00110110 00110101 00110011 00110100 00110010
)
D) Perform XOR with bytes from step B) and C), output 101010000011001001000000101000000000100000010000100010101010000001000000011100000000001000000000001010000001101110100010101010100000000000100010110100101000101101001010101100111100001011110000000100101011100000000000001100001100101111100010001110111110000011111011100110100000001011000000000100100001101000010010000110000000100000001011111000110000001110011010011000000010001100011010100000111100101001011010101100111011101110101010000100000011001100110010000100110111001100001
E) When there is another purchase done by the same credit card, step B) will be performed again and the outputting bytes will be used to against all of the records from step D) (regardless the performance)
F) All retrieved bytes will then be converted back to numbers and check which are able be divided by 2 and 7, the matching records will be treated as a 'return customer'
What I am really wondering is...
- Is the above flow secure enough to protect the customers' card number?
- Is there any further step I could take to make it more secure?
- Any better algorithm or pattern could be applied for step C)?
- Does cost 14 good enough for step A)? Or is the cost/security matter when getting the bytes from credit card?
- Is it possible to crack the full card number by the above method? if so, how long does it take?
- What is the possibility that 2 different credit card clashes the above method? (same outcome)
Sorry I am not good at mathematics, encryption or security, any idea is welcome.
Remark
The first 6 and last 4 digits of the card number are store in the database somewhere else.