Solved

encrypt a string?

Posted on 2008-10-24
23
535 Views
Last Modified: 2010-05-18
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
Comment
Question by:DJ_AM_Juicebox
  • 13
  • 10
23 Comments
 
LVL 53

Expert Comment

by:Infinity08
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

by:DJ_AM_Juicebox
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

by:Infinity08
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

by:Infinity08
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

by:DJ_AM_Juicebox
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

by:Infinity08
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

by:DJ_AM_Juicebox
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

by:Infinity08
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

by:DJ_AM_Juicebox
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

by:Infinity08
ID: 22797076
>> Does that solve the problem?

No ;)

Can you answer these questions I asked earlier ?


>> 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

by:DJ_AM_Juicebox
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 53

Expert Comment

by:Infinity08
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

by:DJ_AM_Juicebox
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).
6) Read result back in.
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

by:Infinity08
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

by:DJ_AM_Juicebox
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

by:
Infinity08 earned 500 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

by:DJ_AM_Juicebox
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

by:Infinity08
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

by:DJ_AM_Juicebox
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

by:DJ_AM_Juicebox
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

by:Infinity08
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)

More info on the separate steps :

(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;

}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
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

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

Heh, too late ;)
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
You cannot be 100% sure that you can protect your organization against crypto ransomware but you can lower down the risk and impact of the infection.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now