Link to home
Start Free TrialLog in
Avatar of karna_kk
karna_kk

asked on

Encrypt a CString into an Integer and Decrypt later

I want to encrypt PASSWORD string (entered by the user) to an integer, store it for sometime and later decrypt (through the program) to get the PASSWORD string back.
Avatar of snoegler
snoegler

This is not possible. Say your password is 8 Bytes(=128 Bits) long. There is no way to
squeeze 128 Bits into 32 (or even 16) bits of information without loss.
(If there was, you would have found the world's best compression algorithm)
Of course, when you only allow A-Z and 0-9 (26+10=36 different values per password
character), then you could store a 6 byte long password into a 32-bit integer.

// code sample: packing 6 byte character string (with each byte within 0 and 35)

unsigned long ulPwd,i;
char sPwd[6];
ulPwd=0;
for(i=0;i<6;i++) {
  ulPwd*=36;
  ulPwd+=i;
}
// sPwd[] must be manually converted from 0-9,A-Z(chars) to 0-35(values) before this routine.


// unpacking

unsigned long ulPwd,i;
char sPwd[6];
ulPwd=  /// some value determined before
for(i=0;i<6;i++) {
  sPwd[i]=ulPwd % 36;
  ulPwd-=sPwd[i];
  ulPwd/=36;
}

// after that, sPwd[] contains again values in the range 0-35.
snoegler is right that retrieval is not possible, you must loose information if the string contains more bits of info than can be squeezed into a string (like Snoegler's example you can pack a bit more into an int if you know only a limited range of characters are allowable in the String)

The usual "work round" for this is :-

To Store:
1. Password-String-1 -> Integer-1 : by hashing (e.g. MD5), then store this int into database etc.

To Test Password (say Password-String-2)
1. Password-String2 -> Integer-2 : by hashing (e.g. MD5)
2. Retrieve Integer-1
3. Compare Integer-1 to Integer-2


Avatar of karna_kk

ASKER

Allright. My problem is that I accept the PASSWORD from the user for once and this PASSWORD has to be sent to an Engine - in the encrypted form. The Engine on receiving the encrypted PASSWORD, would decrypt to get the string back.
Is there any encryption/decryption format to do such thing. Not necessarily into an Integer (but the datatype has to be compliant with DBMS datatype).

Encrypting a String into another String is OK for me.

Thanks.

Allright. My problem is that I accept the PASSWORD from the user for once and this PASSWORD has to be sent to an Engine - in the encrypted form. The Engine on receiving the encrypted PASSWORD, would decrypt to get the string back.
Is there any encryption/decryption format to do such thing. Not necessarily into an Integer (but the datatype has to be compliant with DBMS datatype).

Encrypting a String into another String is OK for me.

Thanks.

ASKER CERTIFIED SOLUTION
Avatar of dinom
dinom

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Can you gimme some code on that. I see lots of parameters that I have never used. I couldn't work on those functions which is why I asked for experts comments.

Your support would be highly appreciated.

Thanks.
Hi !

I used the following simple technique to encrypt/decrypt any given file. You can use this technique for encrypting/decrypting your password.

int iKEY = 8 // say. You can use whichever Key you want. But it needs to be known at the encrypt and the decrypt parts of the  program. Infact, I used an array of Keys for better encryption
int iKeys[5] = {1,9,6,2,5};

Anyway, for now lets say iKey = 8

srand(iKey) // iKey acts as the seed for srand.
int iModifier = rand();

char strPwd[10] = "UMARAMA12";
// At the encrypt side, use bit-wise exclusive OR to jumble the password.

for (int i = 0; i < 10; i++)
    strPwd[i] = strPwd[i] ^ iKey;

// Send the encrypted password to the other end, engine.

There Exclusive-Or again. Use the same Key. Only then rand() will give the same random number which you used while encrypting.

srand(iKey) // iKey acts as the seed for srand.
int iModifier = rand();
for (i = 0; i < 10; i++)
  strPwd[i] = strPwd[i] ^ iKey;

strPwd will be decrypted back to UMARAMA12

A WORD OF CAUTION.
This technique works for ASCII char set 0 -126. For characters above that (non-printable) don't Ex-OR. Simply let it pass. In case you hope to get such characters, put the additional check to see if it falls between 0 - 126

Hope this helps you.
umarama, when you use 'unsigned char', it works for 0-255.
BTW: I hope my online banking application doesn't use an algorithm like this :)

Decryption Example

This example reads the encrypted data from the file created by the “Encryption Example” (test1.xxx), decrypts it using the RC2 block cipher, and writes out the plaintext data to another file (test1.txt). The session key used to perform the decryption is read from the ciphertext file.

#include <wincrypt.h>

FILE *hSource = NULL;
FILE *hDest = NULL;
int eof = 0;

HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;

#define BLOCK_SIZE 160
BYTE pbBuffer[BLOCK_SIZE];
DWORD dwCount;

BYTE *pbKeyBlob = NULL;
DWORD dwBlobLen;

// Open source file.
if((hSource=fopen("test1.xxx","rb"))==NULL) {
    printf("Error opening source file!\n");
    goto done;
}

// Open destination file.
if((hDest=fopen("test1.txt","wb"))==NULL) {
    printf("Error opening destination file!\n");
    goto done;
}

// Get handle to the default provider.
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
    printf("Error %x during CryptAcquireContext!\n", GetLastError());
    goto done;
}

// Read key blob length from source file and allocate memory.
fread(&dwBlobLen, sizeof(DWORD), 1, hSource);
if(ferror(hSource) || feof(hSource)) {
    printf("Error reading file header!\n");
    goto done;
}
if((pbKeyBlob = malloc(dwBlobLen)) == NULL) {
    printf("Out of memory!\n");
    goto done;
}

// Read key blob from source file.
fread(pbKeyBlob, 1, dwBlobLen, hSource);
if(ferror(hSource) || feof(hSource)) {
    printf("Error reading file header!\n");
    goto done;
}

// Import key blob into CSP.
if(!CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hKey)) {
    printf("Error %x during CryptImportKey!\n", GetLastError());
    goto done;
}

// Decrypt source file and write to destination file.
do {
    // Read up to BLOCK_SIZE bytes from source file.
    dwCount = fread(pbBuffer, 1, BLOCK_SIZE, hSource);
    if(ferror(hSource)) {
        printf("Error reading data from source file!\n");
        goto done;
    }
    eof=feof(hSource);

    // Decrypt data.
    if(!CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount)) {
        printf("Error %x during CryptDecrypt!\n", GetLastError());
        goto done;
    }

    // Write data to destination file.
    fwrite(pbBuffer, 1, dwCount, hDest);
    if(ferror(hDest)) {
        printf("Error writing data to destination file!\n");
        goto done;
    }
} while(!feof(hSource));

done:

// Free memory.
if(pbKeyBlob) free(pbKeyBlob);

// Destroy session key.
if(hKey != 0) CryptDestroyKey(hKey);

// Release provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);

// Close source file.
if(hSource != NULL) fclose(hSource);

// Close destination file.
if(hDest != NULL) fclose(hDest);
 
Thanks snoegler for the correction : 'unsigned char'.
Umarama's solution best suits my needs. Dinom's code is w.r.t FILES, but I was looking for strings. Anyways, I thank everyone in helping me.
Why have you given points to dinom if my solution best suits your needs ??
Hi Umarama, I tried to write a mail to you but couldn't find the email address. The options that I had to choose were related to DINOM. There was no other option and since I wanted to close the question, I had to choose one among the available. The options dialog never had your name for me to choose. I wonder if there is something ???? with the program.

Thanks for the help.

-Karna.
A small comment: using a bit-wise exclusive or as the encryption algorithm will yield a very weakly encrypted password (one which could probably be hack with the computational force of a hand-held calculator).  If you will be using xor as the algorithm make sure that what you are encrypting is close to worthless from the start since it will be as soon as someone breaks the algorithm.  I reality you would want to use some kind of stronger encryption (128-bit key, etc...)

Dinom
I totally agree with dinom. Using XOR you could even calculate the original value just with
a paper and a pen :)
I hope your application doesn't need to fulfill some security requirements ...
Dear Dinom & snoegler - Guess you both are trying to under-estimate the XOR algorithm. It's not simple XOR. KEYS are used to determine the translation logic based on random functions. Infact, using an array of Keys, say Keys[100] one can XOR each byte of the string to be encrypted with a different key. Hence, calculating the original value with a paper & pen is nothing but a joke ! The Keys[] needs to be in encapsulated properly - that's all. This applies to any algorithm where the coding technique needs to be protected !

karna_kk - Don't worry about the points. And rest assured, the XOR algorithm is safe as long as the Keys are safe. Use Keys[] to have better security. I used this technique where security was indeed an issue and this XOR technique was published in a well reputed magazine !
Please don't get me wrong ...
Take a look at this (password = "2ex1w")
1. 'A' -> 's'(115)
2. 'B' -> '''(39)
3. ' ' -> 'X'(88)
4. 'C' -> 'r'(114)
5. ' ' -> 'W'(87)
6. 'D' -> 'v'(118)
7. ' ' -> 'E'(69)
8. 'E' -> '='(61)

Now let's say that 'A','B','C','D' could be replaced by words. So between each word there is a space.
If you knew where the spaces were, then you could easily find out the original password there:
Position 3: 'X' XOR 32 -> 'x'(120)
Position 5: 'W' XOR 32 -> 'w'(119)
Position 7: 'E' XOR 32 -> 'e'(101)

It is almost impossible with the formatting options here to show the exact process. But believe me, a friend of mine was a hobby-hacker, and an algorithm like this you can even crack with a
brute force algorithm. All you need is a list of common words
followed by spaces, and a bit time.
***
Everyone who *tries* to hack your encrypted string *will* hack
it. That is what i mean. I know that somebody who's just curious
won't find out the original password. But somebody who wants it
will ever get it.
***
Especially because karna_kk is using this technique to encrypt
an *PASSWORD* maybe for an online banking application (!!with
the next problem that you'd need another password, and where
would you get it ... if you use always the same, then your
master password gets hacked one time, and everyone who likes
can access the original data!!!!), i would *REALLY* suggest not
to do it this way.
***
Here in germany, the telephony and internet provider "TELEKOM"
has had a big scandal about how the password and username was
stored in its internet access tool. Now guess which way it was
encrypted :)
( two 16-17 year old boys hacked the passwords of some 1000
users )
The issue is - what the F**k is behind those passwords.  Your XOR encryption algorithm is most likely fine, as long as the passwords don't have much value.  Again on-line banking/trading where the passwords can lead to 100's of thousands of dollars will certainly require a stronger method.  Umarama, I'm not underestimating anything.  Give me a small array of Sun workstations and I'll be able to hack this XOR method inside of 1 week.  What does this mean - if your using this XOR method to encrypt, make sure that what the algorithm is hiding is not worth 1 week on an array of sun workstations (let's say 5000 dollars).  Now, I'm no encryption expert but most strong encryption algorithms use large (128-bit+) keys and somehow incorporate PRIME numbers.  Anyway,  I really can't waste much more time arguing this point, and it's nothing against you personally Umarama but grow up!  We are here to use what we can to enlighten, inform, and produce.  You must look at the algorithm OBJECTIVELY, just because it isn't the best encryption algorithm doesn't make you any less of a man/woman.  Keep on truckin'
Hey pals,
You seem getting into major criticism. As i mentioned earlier, my situation best meets with the XOR logic. Agreed that the other logics are fine, but just that I wanted something fast and simple. I'm done.
Now please stop this criticism unless it is healthy for all of us. Once again, I thank everybody involved in solving the issue.

-Karna.