Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# encrypt a string?

Posted on 2008-10-24
Medium Priority
573 Views
Hi,

I'd like some encryption routine where I provide an input string and a key, and I get back an encrypted string. To decrypt, I supply the encrypted string and the key, and get back the original string.

The encrypted string should only have characters that are 7-bit ASCII characters - which is my main problem. All the solutions I've found produce encrypted strings out of that range.

Anyone have any suggestions on where to start?

Thanks
0
Question by:DJ_AM_Juicebox
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 13
• 10

LVL 53

Expert Comment

ID: 22796192
The choice of encryption algorithm depends on what kind of security you need, and what it'll be used for.

Don't worry if the output is binary data. You can always use an algorithm like Base64 to transform the binary data into readable ASCII :

http://en.wikipedia.org/wiki/Base64
0

Author Comment

ID: 22796471
Ah ok I have to read the link again, but I already have an encryption method that was working for my purposes (AES), the problem is that the output would be out of the 7-bit ASCII range (would output signed eight-bit values)

This is the source I am using: http://www.codeproject.com/KB/security/aes.aspx

Will the base 64 encoding increase the length of the output string though? I only have space to store 64 characters - so if someone gave me a 64 character string to encrypt, I can't store any more characters than the source length...

Thanks

0

LVL 53

Expert Comment

ID: 22796658
>> Will the base 64 encoding increase the length of the output string though?

Yes. By a factor of 4/3 (3 bytes are encoded into 4 characters)

>> I only have space to store 64 characters

compression ;) Compress the input data, encrypt the compressed data, base64 encode the encrypted data. When done correctly, you should get a string of max. 64 bytes as output :)
0

LVL 53

Expert Comment

ID: 22796751
Or, looking at it differently :

The output (Base64 encoded) can be max. 64 characters.
That means that the encrypted data can be max. 48 bytes.
Which in turn means (assuming 128bit AES) that the input data can be max. 48 bytes.

So, you need to compress the 64 input characters into 48 input bytes.
This is easy to achieve using a Base64 decoder, but only if there are max. 64 valid characters in the input string. Is that so ?
0

Author Comment

ID: 22796756
Ok sounds good, can you just give me a general idea as to what to look for:

1) Which compression method am I wanting to search for?
2) Am I looking for a base64 encoding library, or is it simple enough that there's probably a code snippet out there I can cut and paste? Any specific name for the type of base64 encoding I should use, or just 'base64'?

Thanks
0

LVL 53

Expert Comment

ID: 22796785
>> but only if there are max. 64 valid characters in the input string. Is that so ?

What are the valid characters in the input string ?
0

Author Comment

ID: 22796844
Hmm ok I'm not sure that I follow - but the input will always be max 64 ASCII characters - in the 0 to 127 range.

Does that work?
0

LVL 53

Expert Comment

ID: 22796952
>> in the 0 to 127 range.

Ok. Then you can use a Base128 encoding, so :

1) Base128 decode the input string
2) encrypt the result from 1)
3) Base128 encode the result from 2)

The only problem is that the output of 1) will be 56 bytes long, and that's no valid input for AES (not a multiple of 16). You'll need an encryption method that encrypts 56 bytes into 56 bytes.

Are you sure that all characters 0 to 127 are valid. Can it be limited to 64 characters only ?
Can you limit the size of the input string to less than 64 ?
Can the output string size limitation of 64 characters be relaxed ?
0

Author Comment

ID: 22797040
>> The only problem is that the output of 1) will be 56 bytes long, and that's no valid input for AES (not a multiple of 16)

Ok so I'm already padding the input string with spaces if less than 64 characters, this is ok because I'm not encrypting a password, it's just a sentence so spaces at the end get stripped off anyway.

Does that solve the problem?

Thanks
0

LVL 53

Expert Comment

ID: 22797076
>> Does that solve the problem?

No ;)

>> Are you sure that all characters 0 to 127 are valid. Can it be limited to 64 characters only ?
>> Can you limit the size of the input string to less than 64 ?
>> Can the output string size limitation of 64 characters be relaxed ?
0

Author Comment

ID: 22797154
>> Are you sure that all characters 0 to 127 are valid. Can it be limited to 64 characters only ?
Ah sorry I misread- I thought you meant can the length be limited to always being 64. It is unlikely anyone would ever enter a character in the full 0 to 127 range, in reality it's only going to be characters a user can type on a keyboard. I can do a pre-scan, if I find a character not enter-able on the keyboard, just tell them encryption is not possible with the given input. I think in 99% of cases that will work.

>> Can you limit the size of the input string to less than 64 ?
No

>> Can the output string size limitation of 64 characters be relaxed ?
No

0

LVL 53

Expert Comment

ID: 22797228
If you can limit the input to 64 valid characters, you can use Base64 (or at least a modified version of it) together with AES.

If not, then you can still use the same technique, but you won't be able to use AES, since that would result in an output string that is longer than 64 bytes. You'll need to use a different encryption algorithm that can encrypt 56 bytes into 56 bytes.

You cannot rely on a general purpose compression method, since it would not be guaranteed that the output would be less than 64 characters.
0

Author Comment

ID: 22797232
One other question, on this line:

"The only problem is that the output of 1) will be 56 bytes long, and that's no valid input for AES (not a multiple of 16)."

Although the user can only give me max 64 characters, I can internally add however many extra characters I want. So if the Base128 will spit out a result of 64bytes if the input is like 80 characters, I can do that internally. Here is my workflow:

1) User gives me a string max 64 characters.
2) I can internally pad it to like 80 characters.
3) Use the base 128 method and spit out 64 bytes.
4) Use AES on the output from 3.
5) Write result from 4 to file (which is now always 64 characters long).
7) Decrypt it using AES, this is still 64 long.
8) Revese base 128 it, this may be 80 long.
9) Truncate junk I added to the end in step 2, show that to user as the original input.

I don't know if the above makes sense at all, just wanted to say that internally I can add anything necessary to get it to output 64 chars, it's just when I write the value to disk for example, it has to be max 64 chars.

Thanks
0

LVL 53

Expert Comment

ID: 22797643
>> Although the user can only give me max 64 characters, I can internally add however many extra characters I want.

Yes, I know. But we WANT the encryption to output only 56 bytes. And that's not possible with AES.

>> 5) Write result from 4 to file (which is now always 64 characters long).

64 bytes ... not 7 bit characters as you require (at least, that was your original question).

So, as I said, you have a few options :

1) Limit the input size to less than 64 characters. You said that's not an option
2) Have an output size of more than 64 characters. You said that's not an option
3) Limit the input alphabet (valid characters) to 64 characters. Then you can use AES together with a modified version of Base64
4) Use a different encryption algorithm that can encrypt 56 bytes into 56 bytes

Only options 3) and 4) remain - up to you which one you prefer :)
0

Author Comment

ID: 22798074
Ah ok, looks like I'll just need to go with a method that can encrypt 56 bytes into 56 bytes, because the user could input values 32 to 127 from the keyboard unfortunately.

Can you recommend such an algorithm?

Thanks
0

LVL 53

Accepted Solution

Infinity08 earned 2000 total points
ID: 22798368
>> Can you recommend such an algorithm?

You could use Rijndael instead of AES. With a block size of 28 bytes (224 bits) : Rijndael-224.

So, in that case, the whole process would be :

(a) Base128 decoding of the input string (64 characters -> 56 bytes)
(b) Rijndael encryption of the result of (a) (56 bytes -> 56 bytes)
(c) Base128 encoding of the result of (b) (56 bytes -> 64 characters)

Note that the Base128 decoding is very straightforward : you only take the 7 relevant bits of each character, and concatenate them into a byte stream. So, the 7 bits of the first character together with 1 bit of the second characters form the first byte (8 bits), etc.
The same for Base128 encoding, but the other way around ;)
0

Author Comment

ID: 22800047
Ok, I think I get it. Is there some C++ implementation of Rijndael with an option of using a 28 byte block size that you can refer me to?

Thanks
0

LVL 53

Expert Comment

ID: 22800291
Rijndael-224 is not very common, so I'm not sure whether there's a library available for it. But you can obviously always write your own ;) (or do a bit of Google searching)

Block ciphers with a 224bit block size aren't common in fact (and that's why I set it as the last option in my list of 4 options). The easiest would be to go with one of the other 3 solutions.
0

Author Comment

ID: 22806390
Hi Infinity,

Took a look at the options again - what's the max number of characters I could have with option #1? That might be the easiest thing -

Thanks
0

Author Comment

ID: 22808759
Hi again Infinity, I'm gonna open a new Q for this, I think you answered my original question.

Thanks
0

LVL 53

Expert Comment

ID: 22810889
>> Took a look at the options again - what's the max number of characters I could have with option #1? That might be the easiest thing -

Assuming these limitations (as mentioned earlier) :

1) input : characters 32 to 127  (count : 96)
2) output : characters 32 to 127  (count : 96)
3) encryption algorithm : AES
4) size of output : max. 64 characters

the max. input size you can have is 58 characters.

Like this :

(a) Base96 decoding of the input string (58 characters -> 48 bytes)
(b) AES encryption of the result of (a) (48 bytes -> 48 bytes)
(c) Base64 encoding of the result of (b) (48 bytes -> 64 characters)

(a) Base96 decoding basically means an algorithm like below (note that uint384 is an imaginary 48 byte unsigned integer type - specific implementation depends on you)
(b) basic AES encryption with a 128, 192 or 256 bit key (192 seems nicest).
(c) basic Base64 encoding - nothing special (plenty of existing code out there)
``````/* Base96 decoding */
char input[58];              /* <--- the input (58 characters in range 32-127) */
int i = 0;
uint384 output = 0;
for (i = 0; i < 58; ++i) {
unsigned int c = (input[i] - 0x20) % 96;       /* <--- in 0-95 range */
output = (output * 96) + c;
}

/* Base96 encoding */
uint384 input;               /* <--- the input (48 bytes) */
int i = 0;
char output[58] = { 0 };
for (i = 57; i >= 0; --i) {
output[i] = 0x20 + (input % 96);               /* <--- in 32-127 range */
input /= 96;
}
``````
0

LVL 53

Expert Comment

ID: 22810897
But it's probably more practical to use Base128 for the first step instead of Base96 :

(a) Base128 decoding of the input string (54 characters -> 48 bytes)
(b) AES encryption of the result of (a) (48 bytes -> 48 bytes)
(c) Base64 encoding of the result of (b) (48 bytes -> 64 characters)

which would limit the input to 54 characters.
0

LVL 53

Expert Comment

ID: 22810902
>> I'm gonna open a new Q for this

Heh, too late ;)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are many Password Managers (PM) out there to choose from. PM's can help with your password habits and routines, but they should not be a crutch you rely on too heavily. I also have an article for company/enterprise PM's.
Businesses who process credit card payments have to adhere to PCI Compliance standards. Hereâ€™s why thatâ€™s important.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Botâ€¦
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
###### Suggested Courses
Course of the Month4 days, 23 hours left to enroll