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 - [EMAIL PROTECTED] All your branches are belong to me! SRM: Site Resource Manager - www.vl-srm.net ----------------------------------------------------------------------- -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php