Re: Crypto++ extension happenings
| From: | derick@php.net | Date: | Sun, 17 Mar 2002 00:53:30 +0000 |
| Subject: | Re: Crypto++ extension happenings | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-81368@lists.php.net to get a copy of this message | ||
Hello,
I'm currently designing a new 'encryption' extension which should be able
to have different backend encryption libaries like mcrypt and crypto++.
however this extension will be developped with an OO approach and for ZE2.
Th eidea is only in my mind at this moment, but I'm sure we can get a API
defined which supports both of these libraries. What do you think of this?
Derick
On Sat, 16 Mar 2002, J Smith wrote:
>
> As I reluctantly mentioned a few weeks ago, I'm working on a PHP crypto
> extension that uses Crypto++, a C++ library that provides implementations
> for a bunch of crypto and hash algorithms. I was reluctant to bring it up
> because I didn't know if I was going to finish it at all, and I didn't want
> to get anybody's hopes up. The rationale behind the extension was partially
> because we need a crypto library at work that we can use on win32 platforms
> for a Windows Media Services plugin and one that PHP can use to create
> ciphertext compatible with the aforementioned plugin. Unfortunately,
> libmcrypt now requires cygwin on win32, and that sort of depedency would be
> hellish for a WMS plugin. Crypto++ works fine on Windows using VC++, and
> also works fine on UNIX systems using g++. Thus, a crypto extension for PHP
> that works on both major platforms.
>
> Well, things have come along a bit further, and although the extension is
> still quite a way from being complete, it's getting there. The basic
> structure of the extension goes something like this:
>
> - there's a base class in C++ that a template inherits from that provides
> the basic members and methods needed to encrypt and decrypt messages, along
> with all of the usual methods that allow you to set the IV for a crypto
> algorithm, the secret key, key length, mode (CBC, ECB, etc.), and
> plaintext. The base class is pure abstract virtual, as is the template that
> encapsulates it. (The template may seem a bit unnecessary, but it's used to
> set things like the block size for ciphers with variable block sizes and
> such. The base class it derives from makes things easier when dealing with
> C++'s templates, which allows it to compile on several compilers, like g++
> and VC++, which all seem to disagree on how to use templates.)
>
> - from there, there are a bunch of classes that provide interfaces to the
> various crypto algorithms, like Blowfish, 3-Way, Rijnadael, etc. So far,
> I've only implemented those three algorithms, but others will be done
> eventually, like the various CAST ciphers, RC5, etc. So far I've only
> worked with block ciphers -- I haven't started anything with the stream
> ciphers, like ARC4, WAKE, etc. All of the more popular block cipher modes
> are working, like OFB, CFB, several CBC padding modes, etc.
>
> - on the hash side, there's a base hash class, from which various other
> classes derive that provide interfaces to the hash algorithms. So far, MD5,
> MD2, Panama and RIPEMD160 are the only hashes I've implemented; HAVAL and
> others will follow. (Although, for whatever reason, HAVAL is being a bitch
> and doesn't like compiling properly. Don't know why yet.)
>
> Besides all of the C++ stuff, I've been working on C functions to access
> from the PHP code. (extern "C" stuff, that all jazz.) They're mostly
> complete for the cipher side; I haven't started on C stuff for the hashes
> yet.
>
> I'm thinking the PHP fuctions themselves will work much like the mcrypt
> library, something like described below. These function names are all
> subject to change, obviously, since I haven't started writing this portion
> of the project yet. I may end up going the object oriented route using PHP
> classes; I'm not sure yet. Depends on feedback. (And more importantly, what
> work wants -- please remember, this extension is being worked on for my
> job; the fact that I can allow everyone else to use it as free software is
> a luxury.)
>
>
> - resource cryptopp_create_cipher(int cipher) -- cipher is a constant that
> refers to the cipher algorithm, like CRYPTOPP_CIPHER_BLOWFISH, or
> CRYPTOPP_CIPHER_AES for AES/Rijnadael. The function returns a PHP resource
> that will be used for the other functions, or false on error.
>
> - bool cryptopp_destroy_cipher(resource cipher) -- closes a cipher.
>
> - bool cryptopp_set_rand_iv(resource cipher, int length [, int rand]) --
> creates a random IV for cipher of the length specified. This is created via
> /dev/urandom or /dev/random on systems that support them; otherwise, it
> uses the standard rand() function. The rand argument can be used to specify
> the method used to create the IV, i.e. CRYPTOPP_RAND_URANDOM for
> /dev/urandom, CRYPTOPP_RAND_RAND for the rand() function, etc. Returns true
> on success, false on error. By default, win32 systems will likely use the
> rand() function, while systems that can provide either /dev/random or
> /dev/urandom will use one of them, preferably urandom.
>
> - bool cryptopp_set_iv(resource cipher, string iv [, bool hex]) -- add a
> specific IV to the resource. hex is used to determine whether the IV being
> added is being given in hex or in binary, with binary being the default.
> True/false on success/error.
>
> - string cryptopp_get_iv(resource cipher [, bool hex]) -- returns the IV of
> resource or false on error. hex specifies whether the IV should be returned
> in binary or in hex, with binary being the default. false on error.
>
> - bool cryptopp_set_mode(resource cipher, int mode) -- sets the mode of the
> cipher, i.e. CRYPTOPP_MODE_PADDED_CBC, CRYPTOPP_MODE_ECB, etc. false on
> error, true on success.
>
> - int cryptopp_get_mode(resource cipher) -- gets the mode the current
> cipher is using, or false on error.
>
> - bool cryptopp_set_plaintext(resouce cipher, string plaintext) -- set the
> plaintext of the cipher. true/false on success/error. I may add a hex
> argument here, as well as a length argument.
>
> - string cryptopp_get_plaintext(resource cipher [, bool hex]) -- get the
> plaintext of the resource. false on error. Returns in binary by default.
> (Might remove the hex argument here.)
>
> - bool cryptopp_set_ciphertext(resource cipher, string ciphertext [, bool
> hex) -- set the ciphertext of the resource. hex determines whether the
> input is in hex or binary, with binary being the default. Returns
> true/false on success/error.
>
> - string cryptopp_get_ciphertext(resource cipher [, bool hex]) -- get the
> ciphertext of the resource. Binary by default. Returns false on error.
>
> - bool cryptopp_set_key(resource cipher, string key [, bool hex]) -- set
> the key, yadda, yadda.
>
> - string cryptopp_get_key(resource cipher [, bool hex]) -- returns the key
> in bin or hex, bin the default, returns false on error.
>
> - bool cryptopp_set_keylength(resource cipher, int keylength) -- sets the
> keylength of the cipher, which may be different than the actual length of
> the key being used. (For instance, you can have a secret key that is in
> reality 32 characters long, but only the first 16 of those characters are
> actually used. 3-way is like this, as it is uses a fixed keylength of 12.)
> True/false on succes/error.
>
> - int cryptopp_get_keylength(resource cipher) -- gets the keylength of the
> resource, or false on error. This should always be checked after setting
> the keylength, as it might not set to what you're expecting. For instance,
> Rijnadael uses a variable keylength of 16, 24 or 32, and if you try to set
> they keylength to something else, like 56, it rounds the keylength off to
> the next lowest correct keylength (32). Likewise, setting a keylength of 12
> in reality sets the keylength to 16. Maybe a notice or warning should be
> raised here...
>
>
> For variable block-size ciphers, there will be two matching functions to
> set and get those -- cryptopp_set_block_size() and
> cryptopp_get_block_size().
>
>
> - bool cryptopp_encrypt(resource cipher) -- encrypt the resource using the
> settings provided above. This will set the ciphertext to something you can
> get using cryptopp_get_ciphertext(). Returns true/false as usual.
>
> - bool cryptopp_decrypt(resource cipher) -- same as above, but obviously it
> decrypts ciphertext into plaintext.
>
>
> There will be a few other functions for the crypto half of the project, but
> those are the main ones.
>
> For the hash side of things, there will be functions similar to those
> above. I may call them hashpp_* to differentiate from the crypto functions.
> Not sure yet. For the sake of example, though...
>
> - resource hashpp_create_hash(int hash) -- returns a resource to be used
> with the hash functions. hash is the constant refering to one of the hash
> algorithms, like CRYPTOPP_HASH_MD5, etc. Returns false on error.
>
> - bool hashpp_destroy_hash(resource hash) -- destroys a hash resource.
>
> - bool hashpp_set_plaintext(resource hash, string plaintext [, bool hex])
> -- same deal as cryptopp_add_plaintext(). Similarly, hashpp_get_plaintext()
> will get the plaintext.
>
> - bool hashpp_set_hashtext(resource hash, string hashtext [, bool hex]) --
> sets the hashtext of the resource. Naturally, you can't convert hashtext
> back to plaintext, but this will still be useful as we'll see below.
> hashpp_get_hashtext() compliments the function.
>
> - bool hashpp_hash(resource hash) -- hashes the plaintext into hashtext,
> which you can get using hashpp_get_hashtext().
>
> - int hashpp_validate(resource hash) -- if you have both the plaintext and
> the hashtext and you want to see quickly if the hashtext provided matches
> the plaintext for the current algorithm, use this function. Returns a
> positive value if they match, 0 if they don't, and false (or maybe -1) on
> error, as a bad match doesn't constitute a real error.
>
>
> There may be other functions added, specifically for hashes with multiple
> block sizes and such.
>
> Other functions that will find their way into the extension eventually --
> functions for stream ciphers, maybe some public/private key stuff.
>
> So basically, you'd use the extension thusly (without any error checking):
>
> <?php
>
> $crypto = cryptopp_create_cipher(CRYPTOPP_CIPHER_BLOWFISH);
> cryptopp_set_plaintext($crypto, "this is plaintext");
> cryptopp_set_rand_iv($crypto, 16);
> cryptopp_set_mode($crypto, CRYPTOPP_MODE_PADDED_CBC);
> cryptopp_set_key($crypto, "this is a secret key");
> cryptopp_encrypt($crypto);
>
> print "Plaintext: " . cryptopp_get_plaintext($crypto) . "<br>\n";
> print "IV: " . cryptopp_get_iv($crypto, true) . "<br>\n";
> print "Secret key: " . cryptopp_get_key($crypto) . "<br>\n";
> print "Ciphertext: " . cryptopp_get_ciphertext($crypto, true) .
> "<br>\n";
>
> crypto_destroy_cipher($crypto);
>
> ?>
>
> Which gives:
>
> Plaintext: this is plaintext
> IV: 0B273F291168170A265F755401602A7B
> Secret key: this is a secret key
> Ciphertext: 1EC05EEB11F127C3CAF929D280E6296EF54679E7F6CAD910
>
> Decrypting is similar -- just set the ciphertext using
> cryptopp_set_ciphertext(), call cryptopp_decrypt() and check out
> cryptopp_get_plaintext(). (Obviously, set the IV, mode and secret key
> accordingly before calling cryptopp_decrypt().) The hash portion of the
> extension works similarly, but you obviously can't retrieve the plaintext
> from a hash. (At least, definitely not easily.)
>
>
> There is a lot left to do on this extension, so it's not going to be ready
> for a while. I just figued I would let people know it's still being worked
> on. I have no idea when I'll finish the extension, so don't hold your
> breath if you're interested.
>
> Comments are appreciated.
>
> J
>
>
> --
> PHP Development Mailing List <http://www.php.net/>
> To unsubscribe, visit: http://www.php.net/unsub.php
>
-----------------------------------------------------------------------
PHP: Scripting the Web - derick@php.net
All your branches are belong to me!
SRM: Site Resource Manager - www.vl-srm.net
-----------------------------------------------------------------------