21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

database does not support binary strings. You want to avoid growing the message<br />

itself (sometimes database fields have length limits) and thus want to avoid encoding<br />

binary data into a representation like base64.<br />

Solution<br />

Encrypt the data using a stream cipher (or a block cipher in a streaming mode). Do<br />

so in such a way that you map each byte of output to a byte in the valid character set.<br />

For example, let’s say that your character set is the 64 characters consisting of all<br />

uppercase and lowercase letters, the 10 numerical digits, the space, and the period.<br />

For each character, do the following:<br />

1. Map the input character to a number from 0 to 63.<br />

2. Take a byte of output from the stream cipher and reduce it modulo 64.<br />

3. Add the random byte and the character, reducing the result modulo 64.<br />

4. The result will be a value from 0 to 63. Map it back into the desired character<br />

set.<br />

Decryption is done with exactly the same process.<br />

See Recipe 5.2 for a discussion of picking a streaming cipher solution. Generally, we<br />

recommend using AES in CTR mode or the SNOW 2.0 stream cipher.<br />

Discussion<br />

If your character set is an 8-bit quantity per character (e.g., some subset of ASCII<br />

instead of Unicode or something like that), the following code will work:<br />

typedef struct {<br />

unsigned char *cset;<br />

int csetlen;<br />

unsigned char reverse[256];<br />

unsigned char maxvalid;<br />

} ENCMAP;<br />

#define decrypt_within_charset encrypt_within_charset<br />

void setup_charset_map(ENCMAP *s, unsigned char *charset, int csetlen) {<br />

int i;<br />

s->cset = charset;<br />

s->csetlen = csetlen;<br />

for (i = 0; i < 256; i++) s->reverse[i] = -1;<br />

for (i = 0; i < csetlen; i++) s->reverse[charset[i]] = i;<br />

s->maxvalid = 255 - (256 % csetlen);<br />

}<br />

void encrypt_within_charset(ENCMAP *s, unsigned char *in, long inlen,<br />

unsigned char *out, unsigned char (*keystream_byte)( )) {<br />

Encrypting in a Single Reduced Character Set | 147<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!