Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encrypt and Decrypt a string to fixed length

I looked into so many examples and tried several articles. But none of them solved my issue.

I want to encrypt my Primary Column Value in Database(INTEGER Value) and show it in the URL. I want my URL to be simple and readable, so I don't want lengthy encryption values. Mostly, I am looking around 5 to 7 characters in length.

Is this possible ? If so, what would be the best approach ?

Encrypt and decrypt a string

http://www.codeproject.com/Tips/306620/Encryption-Decryption-Function-in-Net-using-MD-Cry

like image 413
Chatra Avatar asked Feb 06 '16 22:02

Chatra


People also ask

What encryption ends with ==?

A Base64 string will end with == if and only if the number of bytes it encodes, mod 3, equals 1. Do you see the pattern? It happens that 16-byte (128-bit) encryption keys are very commonly encoded in Base64, and since 16 mod 3 = 1, their encoding will end with == .

What does it mean to encrypt a string?

Encrypts a string, using a symmetric key-based algorithm, in which the same key is used to encrypt and decrypt a string. The security of the encrypted string depends on maintaining the secrecy of the key, and the algorithm choice.


1 Answers

As per you requirements, your integers will have no more than 6 chars (999999) and the encoding should be max 7 chars, so a XOR of 24 bits will do it:

Beware this method is esily reversible by a bruteforce attack, but will hide the real numbers for the majority of the mortals.

First we use a three byte key (the values are just examples, take the ones you like the most:

byte[] theKey = new byte[]{ 34, 56, 98 }; 

Then to encode the integer we take the first three bytes (the fourth byte is not necessary as your INT will not use it, only 20 bits can store up to 1M, so the nearest byte count are three) and we XOR each one with the correpsonding byte at the key:

int cyphered = ((theValue & 0xff) ^ theKey[0]) | 
               ((((theValue >> 8) & 0xff) ^ theKey[1]) << 8) | 
               ((((theValue >> 16) & 0xff) ^ theKey[2]) << 16);

And finally, to make the URL's homogeneous you convert it to an string and pad it with zeroes:

string finalValue = cyphered.ToString().PadLeft(7, '0');

To reverse the value just XOR it again with the key:

int cyphered = int.Parse(theStringYouReceived);

int decyphered = ((cyphered & 0xff) ^ theKey[0]) | 
                 ((((cyphered >> 8) & 0xff) ^ theKey[1]) << 8)| 
                 ((((cyphered >> 16) & 0xff) ^ theKey[2]) << 16);

As I say, it's not precissely an AES256 security cipher (:D) but at least will hide the numbers from the curious.

EDIT: here is the test case, it works as expected:

            byte[] theKey = new byte[] { 34, 56, 98 }; 
            int theValue = 1413;

            int cyphered = ((theValue & 0xff) ^ theKey[0]) |
           ((((theValue >> 8) & 0xff) ^ theKey[1]) << 8) |
           ((((theValue >> 16) & 0xff) ^ theKey[2]) << 16);

            string finalValue = cyphered.ToString().PadLeft(7, '0');

            int scyphered = int.Parse(finalValue);

            int decyphered = ((scyphered & 0xff) ^ theKey[0]) |
                             ((((scyphered >> 8) & 0xff) ^ theKey[1]) << 8) |
                             ((((scyphered >> 16) & 0xff) ^ theKey[2]) << 16);
like image 177
Gusman Avatar answered Oct 31 '22 23:10

Gusman