Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Encryption using perl core functions only

by redhotpenguin (Deacon)
on Nov 25, 2007 at 21:52 UTC ( #652870=perlquestion: print w/replies, xml ) Need Help??

redhotpenguin has asked for the wisdom of the Perl Monks concerning the following question:

Greetings monks

I am transmitting data over a plain text connection and I need a way of encrypting and decrypting the data using only core perl functions since the receiving end is an embedded platform using a basic installation of perl with no modules. On top of that, crypt isn't implemented in perl :) I've tried using pack('C*', unpack('C*', $string)), but it's returning control characters for some non aZ-zZ0-9 characters on decoding (new‡7\cU\cM\cK\cK?3\cM\cKQ\cK\cW).

I saw a two line implementation of the rsa algorithm in perl but I'm looking for something more lightweight because the client only has 8 megs of ram and a small processor. I've looked at rot13 implementations in perl but to quote, 'it is not much stronger than a one meter cardboard fence'. Any thoughts? Remember, I can't use any modules.

update - a shared secret approach here would be fine, my main concern is putting some level of security in so that the data is not there for the taking.

update - thanks to perrin for the spot, Crypt::Blowfish_PP is a module with no dependencies and uses perl core functions only, I'm going to try it out on my broadcom embedded platform.

update - embedded Blowfish_PP successfully, it takes 12 seconds to construct the blowfish object but hey it works!

  • Comment on Encryption using perl core functions only

Replies are listed 'Best First'.
Re: Encryption using perl core functions only
by Limbic~Region (Chancellor) on Nov 25, 2007 at 22:32 UTC
    On top of that, crypt isn't implemented in perl :)

    You must be talking about the Unix utility and not the C library since crypt is a built-in perl function.

    Good encryption algorithms are needed when the algorithm itself is known. This is the case for both symmetrical and asymmetrical encryption. It sounds like you are just trying to obscure the data from a would be bad guy. In this case, you can engineer any data obscure solution you want. In other words, your algorithm itself can be the shared secret.

    For example: Assume you have a very large book where every given word you want to encrypt appears multiple times. You could make your message a secret by replacing each word with the page number and number of words from the beginning where the word appears. Now "11, 5" only means something if both parties know which book is being used. Changing the books regularly in an "out of band" process adds to the difficulty in learning the secret.

    Cheers - L~R

      >> On top of that, crypt isn't implemented in perl :)

      > You must be talking about the Unix utility and not the C
      > library since crypt is a built-in perl function.

      Not exactly, the embedded platform used a microperl installation, and the perl crypt function is not implemented in that version.

      I am trying to obscure the data from a bad guy during transit - that is, I forgo security if they have access to either computer. If I rot the data, my fear is that someone can identify that algorithm easily. I am also looking at the option of using an embedded libopenssl package, and calling out to that through backticks.
        Anonymous Monk/redhotpenguin,
        The perl crypt function wouldn't help you even if it were available since it is a 1-way hashing library and not an encryption/decryption utility.

        If you are only interested in protecting the data in transit, using an existing library like SSL is the lowest cost solution assuming it is available.

        I am not sure you understood what I was saying about using the algorithm as your shared secret. You could pick any data hiding you want that is more sophisticated than rot-13. If you don't provide people access to the algorithm than getting the secret isn't going to be very easy. If you don't believe me, I will design an algorithm and post a secret message to see how long it takes you to decipher it.

        Cheers - L~R

Re: Encryption using perl core functions only
by dragonchild (Archbishop) on Nov 25, 2007 at 23:08 UTC
    Use the Mandelbrot function. It's a very simple function that can be implemented on the clientside, is essentially (though not exactly) one-way, but is easy reversible so that you can have a list of mappings for encryption. It maps (X,Y) coordinates into values in the range 0-N (where N is normally 255).

    This is, essentially, a variation on Limbic~Region's shared-book approach. You can then vary a number of things:

    • Order of coordinates sent. You could send messages in a NxM character grid and send them in col-row order (vs. the normal row-col) order.
    • You can send every Nth coordinate as (Y,X) vs. (X,Y).
    • You can vary the translation of the result of the Mandelbrot from an entry into the ASCII table to an entry into your own table.
    • You can vary the Mandelbrot from a quadratic to a cubic (or quartic) equation. I did this in a course on fractals and instead of the normal Mandelbrot picture, I ended up with a cool picture of two wizards fighting each other. :-)

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Encryption using perl core functions only
by perrin (Chancellor) on Nov 26, 2007 at 00:21 UTC
    Of course you can use modules. There's no difference between code you write and code you take from CPAN as far as Perl is concerned. There are a number of pure-perl modules that implement strong 2-way encryption, like Crypt::Blowfish_PP.
      I don't have or on the embedded platform, but I could remove those pragmas from the module and inline it with my program. There are no dependencies for Crypt::Blowfish_PP too which is nice. Thanks for the pointer, most of the encryption modules I have looked at on CPAN have an XS component and I didn't want to attempt those on the embedded platform.
Re: Encryption using perl core functions only
by tachyon-II (Chaplain) on Nov 26, 2007 at 01:44 UTC

    Xor against a shared secret key is a common approach to lightweight encryption. It is not secure. With a true random key of length greater than the message length it does become more secure.

    my $str = 'hello world!'; my $key = 'just another perl hacker'; my $encoded = xor_encode($str,$key); my $decoded = xor_encode($encoded,$key); print "$encoded\n$decoded\n"; sub xor_encode { my ($str, $key) = @_; my $enc_str = ''; for my $char (split //, $str){ my $decode = chop $key; $enc_str .= chr(ord($char) ^ ord($decode)); $key = $decode . $key; } return $enc_str; }
Re: Encryption using perl core functions only
by KurtSchwind (Chaplain) on Nov 25, 2007 at 22:39 UTC

    Limbic~Region hit it on the head. Essentially we are under the assumption that security through obscurity is good enough. And from what you mentioned it sounds like that is the case.

    As a general rule, security through obscurity is the lowest level of obscurity. "My house is safe because people don't know that the key is on the ledge above the door." generally doesn't fly. But, let's face it. You need to examine security needs on an individual basis and I think a somewhat 'trivial' solution will present itself.

    I used to drive a Heisenbergmobile, but every time I looked at the speedometer, I got lost.
Re: Encryption using perl core functions only
by Porculus (Hermit) on Nov 25, 2007 at 23:01 UTC
    You could take advantage of Perl's Bitwise String Operators to XOR your data against a shared key. This is completely useless against any hacker with half a clue, but is a popular method for obfuscation where true security is not critical. It's marginally more secure than ROT-N, and arguably simpler to implement -- I suspect it may be more efficient too, though I haven't bothered to benchmark anything.

      If your shared key is significantly larger then the plain text and the key is sufficiently random than using the key as a rotating shared key is non trivial or nearly impossible to break. is a similar choice which you may want to look at, the advantage for these is that they require little processing power to compute.

        It's not that simple, unfortunately. If you re-use the key, then you lose that security (the hacker can simply think of a large number of messages as a single large message with a key shorter than the message, at which point you're back where you started); and if you don't re-use the key, you have the problem of getting the new key to the client device securely.

      Hi Porculus - apologies for replying to such an old thread...

      A few years I invented a home-grown encryption for a application I wrote, and used a scheme like you describe. Following your comment, I am concerned about the security of my encryption (which is still in use).

      I am XOR'ing the plaintext against a shared secret "random" key, where the key is approx 50 thousand bytes (compared to a typical plaintext length of 10-500 bytes). The XOR starting position within the key is "random" for each encryption/call (and is then embedded within the encrypted data so the decryption algorithm can find it). The encryption program code and plaintexts are guaranteed to be private, and only the encrypted data is ever made public.

      Can you briefly explain to me how an attacker would break this?

      Many thanks for your help.

        Can you briefly explain to me how an attacker would break this?

        Pretty much the same way you would break rot 13 or any other substitution cipher, easily

Re: Encryption using perl core functions only
by ikegami (Patriarch) on Nov 26, 2007 at 07:14 UTC

      How did you know? I'm looking through the documentation now, and I'm probably reading it wrong, but it looks like the module is fine with being called directly.

        Crypt::Blowfish_PP only provides means of encrypting and decrypting 8-byte blocks. Being able to encrypt and decrypt blocks is just part of "encryption".

        • Were you just passing random length strings to encrypt? You need padding.
        • Were you planning on encrypting every block with the same key? You need chaining.
        • Were you planning on encrypting every conversation with the same key? You need salting.

        Crypt::CBC is a facility to provide padding, chaining and salting.

        That still leaves

        • key management, (How do you give the key to both hosts? How does each host protect the key? How do you know the protection works? What happens when the protection fails? Until when is the key valid? What happens if the key is compromised? etc.)
        • algorithm management, (How do you know Blowfish is still secure? What happens when Blowfish is not secure? How do you know the implementation is secure? What happens when the implementation is no longer secure? etc.),
        • ...

        And that's just to protect the data in transit.

Re: Encryption using perl core functions only
by KurtSchwind (Chaplain) on Nov 25, 2007 at 22:03 UTC

    I did some super lightweight encryption. I used rot-X where X was over the printed charset. So I had punctuation and whatnot in mine.

    A slightly taller fence, but it wasn't hard to do and it passes for small/light encryption. I'd have to double check but I think I was rotating over 96 characters instead of 13.

    Oh, and one more thing. Using 'rot' encryption means that your encrypt and decrypt are the same routine. Which is nice. But it's pretty shoddy encryption.

    I used to drive a Heisenbergmobile, but every time I looked at the speedometer, I got lost.
Re: Encryption using perl core functions only
by gam3 (Curate) on Nov 25, 2007 at 23:24 UTC
    If this is constant TCP connection you might XOR against the rand() function. This should be rather secure except for the transfer of th e shared secret. That being the seed to the srand function. You'll need some way to reset the seed if the computers get out of sync.
    -- gam3
    A picture is worth a thousand words, but takes 200K.
Re: Encryption using perl core functions only
by aquarium (Curate) on Nov 26, 2007 at 01:22 UTC
    i reckon you could get away with: zip the file with a password, and rename as a .rtf, and present it on a www service for the client to pick up using basic authentication.
    if the data is more sensitive than that, then you shouldn't be using an open line in the first place
    the hardest line to type correctly is: stty erase ^H
Re: Encryption using perl core functions only
by moritz (Cardinal) on Nov 26, 2007 at 19:32 UTC
    Just some random thoughts on cryptography and perl:

    • Implementing cryptographic functions is hard and error prone - don't roll your own.
    • Even if you use an existing, tested implementation of your favorite cypher - your setup might still be vulnerable (poor key setup, too few key changes, missing authentication, possible man-in-the-middle attacs, ...)
    • Inventing new algorithms is even harder - don't do it, unless you are really into cryptography. Even if you're good at it, don't used it unless it has gone through peer review.
    • Blowfish is designed to have a slow key setup, so that it's hard to do brute force key guessing. If you need fast key setup, use something else.
    • crypt is intended to be a hash function, not a cypher (although the name suggests differently).

      I agree entirely and personally think that the less we know about the OP context, the less we should condone "security by obscurity". ++ to Moritz and Corion and Perrin and those advocating already written, already tested algorithms and modules.

      As to the idea that keeping your algorithm secret is as good as keeping your key secret, the Snake Oil FAQ from has a section to address this directly, and the folks at the American Cryptogram Association considers it great fun to crack ciphers of an unknown algorithm.

      I humbly seek wisdom.
Re: Encryption using perl core functions only
by zentara (Archbishop) on Nov 26, 2007 at 16:06 UTC
    Here's another example from fokat
    #!/usr/bin/perl use warnings; use strict; #by fokat of perlmonks my $string = 'justanotherperlhacker'; print "$string\n"; my $obscure = pack("u",$string); print "$obscure\n"; my $unobscure = unpack(chr(ord("a") + 19 + print ""),$obscure); print "$unobscure\n";

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Encryption using perl core functions only
by Corion (Patriarch) on Nov 26, 2007 at 17:52 UTC

    Another "lightweight" encryption algorithm is the Tiny Encryption Algorithm, TEA. There are two (conflicting) modules on CPAN for it, Crypt::Tea and Crypt::TEA. Crypt::Tea displays bad taste in the name choice (as it is the latecomer) but it has no prerequisites, while Crypt::TEA needs a C compiler.

Re: Encryption using perl core functions only
by sundialsvc4 (Abbot) on Nov 26, 2007 at 20:19 UTC
    (Blowfish_PP)... good catch! Really, though... good encryption, real encryption, is easy to do even with only a small amount of RAM. One thing not to be overlooked is that quite a few operating-systems ship with encryption-libraries for other purposes, and there are available Perl bindings to them. If you know that your app is being deployed to, say, Windows-32 of any recent vintage, then you also know that this system has its own built-in cipher stack. So it's "not in your own code," and it's "already there." Sure, it's Win32-specific (say), but who cares?

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://652870]
Approved by grep
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2022-05-19 16:43 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (72 votes). Check out past polls.