Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encrypting 30 bit Number into 6 Character Alphanumeric String

I'm looking for an approach to encrypt/obfuscate a 30 bit number.

The results will be grouped into sets of 3 and visible to users as a 6 character alphanumeric encoded with a base32 alphabet, but the user should not be able to pick up a pattern in the alphnumeric strings. For example, the users could see 3 strings: ASDFGH, LKJHGF, ZXCVBN and those might map to the numbers 1073741821, 1073741822, 1073741823. But, it is a pattern they should not be able to easily figure out.

I've looked at a few encryption algorithms, like DES. Here is a bad and naive attempt:

import struct
from Crypto.Cipher import DES
from .baseconv import base32_urlsafe

_KEY = '\x81\x98\xe1\x14<\xb3\xe8\x10'
_encryptor = DES.new(_KEY)

def encrypt_number(number):
    encrypted_i64 = struct.unpack(
        '!Q', _encryptor.encrypt(struct.pack('!Q', number))
    )[0]
    encrypted_i30 = encrypted_i64 >> 34
    return base32_urlsafe.encode(encrypted_i30)

But obviously I won't be able to decrypt the string if ever needed and uniqueness is lost with this approach. Also looked at using XOR, but that is too predictable, since more often then not the numbers will be in a consecutive sequence.

I've never had to encode something like this. So, I'm looking for some encryption algorithms/approaches to research and consider. I'm using python, but ideas or examples using other languages are welcome.

like image 544
d3w4rd Avatar asked Oct 19 '25 11:10

d3w4rd


1 Answers

Format preserving encryption might be helpful here.

For example, the cycle-walking method described in the paper "Ciphers with Arbitrary Finite Domains" by Black and Rogaway seems like a potential solution. E.g. use a 32-bit cipher (Skip32 by Greg Rose is an example). Encrypt your 30-bit input with the cipher. If the result is a 30-bit integer (i.e. the leading 2 bits are 0) then your are done, otherwise keep encrypting with the cipher until you get a 30-bit result. Decryption is done accordingly.

If you don't need a very secure solution then the Hasty Pudding cipher might be a alternative. It can encrypt inputs of arbitrary size. It was submitted to the AES competition, however did not make it very far and hence is not well analyzed. Still I would expect it to be far more appropriate than any ad hoc solutions proposed here on stackoverflow.

like image 188
user12398 Avatar answered Oct 21 '25 12:10

user12398