in reply to Short & Sweet Encryption?

The following will encrypt strings of up to 15 bytes in length into strings of 22 URL-safe bytes.

There is no salting and no chaining, so a lot of security is missing. Do not use this to hide any critical information. Do no use the key used here for anything else.

It is, however, as strong as any other solution in this thread, results in two fewer bytes than the other equally strong contender, and can encode arbitrary data (including nuls and spaces).

# Encrypter use Crypt::Blowfish (); use MIME::Base64 qw( encode_base64 ); my $key = ...; my $plaintext = ...; die("Text to encrypt must be less than 16 bytes long\n") if length($plaintext) >= 16; my $cipher = Crypt::Blowfish->new($key); my $padded_plaintext = pack('Ca15', length($plaintext), $plaintext); my $ciphertext1 = $cipher->encrypt(substr($plaintext, 0 +, 8)); my $ciphertext2 = $ciphertext1 ^ $cipher->encrypt(substr($plaintext, 8 +, 8)); my $ciphertext = $ciphertext1 . $ciphertext2; my $websafe_ciphertext = substr(encode_base64($ciphertext, ''), 0, -2) +;
# Decrypter use Crypt::Blowfish (); use MIME::Base64 qw( decode_base64 ); my $key = ...; my $websafe_ciphertext = ...; die("Text to decrypt must be exactly 22 bytes long\n") if length($plaintext) != 22; my $cipher = Crypt::Blowfish->new($key); my $ciphertext = decode_base64($websafe_ciphertext.'=='); my $ciphertext1 = substr($plaintext, 0, 8); my $ciphertext2 = substr($plaintext, 8, 8); my $padded_plaintext = $cipher->decrypt( $cyphertext1) . $cipher->decrypt($ciphertext1 ^ $cyphertext2); my $plaintext = unpack('C/a*', $padded_plaintext);

Untested.

Update: Now uses chaining.

Replies are listed 'Best First'.
Re^2: Short & Sweet Encryption?
by Anonymous Monk on Oct 25, 2007 at 17:43 UTC
    Above code contained a couple of spelling misstakes, which I've taken the liberty of correcting.

    Also, is there a way to get this approach to work with an arbitrary length plaintext? I.e. with plaintexts more than 16 character in length?

    # Encrypter use Crypt::Blowfish (); use MIME::Base64 qw( encode_base64 ); my $key = ...; my $plaintext = ...; die("Text to encrypt must be less than 16 bytes long\n") if length($plaintext) >= 16; my $cipher = Crypt::Blowfish->new($key); my $padded_plaintext = pack('Ca15', length($plaintext), $plaintext); my $ciphertext1 = $cipher->encrypt(substr($padded_plain +text, 0, 8)); my $ciphertext2 = $ciphertext1 ^ $cipher->encrypt(substr($padded_plain +text, 8, 8)); my $ciphertext = $ciphertext1 . $ciphertext2; my $websafe_ciphertext = substr(encode_base64($ciphertext, ''), 0, -2) +; # Decrypter use Crypt::Blowfish (); use MIME::Base64 qw( decode_base64 ); my $key = ...; my $websafe_ciphertext = ...; die("Text to decrypt must be exactly 22 bytes long\n") if length($websafe_ciphertext) != 22; my $cipher = Crypt::Blowfish->new($key); my $ciphertext = decode_base64($websafe_ciphertext.'=='); my $ciphertext1 = substr($ciphertext, 0, 8); my $ciphertext2 = substr($ciphertext, 8, 8); my $padded_plaintext = $cipher->decrypt( $ciphertext1) . $cipher->decrypt($ciphertext1 ^ $ciphertext2); my $plaintext = unpack('C/a*', $padded_plaintext);
      Yes, use Crypt::Blowfish via Crypt::CBC. That's how it should always be done. It's even relatively much more simple. I used Crypt::Blowfish directly above to attain the specific goals requested by the OP at the cost of reduced security, placing limits on the size of the input and having to do some of CBC's job myself.
      spelling misstakes
      s/misstakes/mistakes/