Hi Pádraic,
Sorry for the problems with the wiki again... I have brought the Java
tools back up; hopefully it will live long enough for you to post your
much appreciated work!
Thank you for your continued patience and dedication. :)
Best regards,
Darby
Pádraic Brady wrote:
> Hi all,
>
> Will post this to the Wiki when it's back from the land of the dead.
> Here's a copy of my Zend_Crypt proposal which intitially implements
> Hashed Message Authentication COde (HMAC) and Diffie-Hellman Key
> Exchange (DH).
>
> It's the wiki formatted form - still readable of course ;).
>
> The Math classes which are currently omitted are located in the referred
> Subversion repository. The code is basically complete barring review
> comments - I got these through the PEAR proposal process over the last
> few weeks for the PEAR OpenID effort.
>
> ------------------------------------------------------------------------
> {zone-template-instance:ZFDEV:Zend Proposal Zone Template}
>
> {zone-data:component-name}
> Zend_Crypt
> {zone-data}
>
> {zone-data:proposer-list}
> [Pádraic Brady|mailto:padraic dot brady at yahoo dot com]
> {zone-data}
>
> {zone-data:revision}
> 1.0 - 13 July 2007
> {zone-data}
>
> {zone-data:overview}
> The purpose of Zend_Crypt is to offer PHP5 implemented cryptographic and
> encryption algorithms for use by other components (e.g. Zend_Mail,
> Zend_OpenId) and application developers themselves. In proposing
> Zend_Crypt, a primary goal is to reduce reliance on disparate
> implementations within the framework by offering very flexible
> implementations which will utilise available PHP5 core extensions. This
> reduces duplication and centralises maintenance of essential core
> cryptographic algorithms.
>
> The two initial Zend_Crypt implementations of the Hashed Message
> Authentication Code (HMAC; RFC 2104) and Diffie-Hellman Key Exchange
> (DH; RFC 2631) are proposed first since they are required algorithms of
> the OpenID 2.0 Authentication Specification. Others will follow should
> the proposal be accepted.
> {zone-data}
>
> {zone-data:references}
> * [Implementations in
> subversion|http://svn.astrumfutura.org/zendframework/trunk/library/Proposed/Zend/Crypt]
>
> *Related PEAR proposals for PHP5/PEAR2*
> * [PEAR Crypt_HMAC2|http://pear.php.net/pepr/pepr-proposal-show.php?id=495]
> * [PEAR
> Crypt_DiffieHellman|http://pear.php.net/pepr/pepr-proposal-show.php?id=496]
>
> *RFC References*
> * [RFC 2104: HMAC: Keyed-Hashing for Message
> Authentication|http://tools.ietf.org/html/rfc2104]
> * [RFC 2631: Diffie-Hellman Key Agreement
> Method|http://tools.ietf.org/html/rfc2631]
> {zone-data}
>
> {zone-data:requirements}
> * *Must* be accompanied by comprehensive unit tests reflecting any RFCs
> which illustrate a testing framework
> * *Must* implement Hashed Message Authentication Code (RFC2104)
> * *Must* implement Diffie-Hellman Key Exchange (RFC2631)
> * *Must* implement Math methods for enabling big integer (> 32 bit)
> support and methods for transforming big integer strings to binary
> forms, and vice versa.
> {zone-data}
>
> {zone-data:dependencies}
> * Zend_Crypt_Math
> * Zend_Exception
> {zone-data}
>
> {zone-data:operation}
> Zend_Crypt will be a collection of cryptographic and encryption classes.
> As such each component can be used in isolation, or to perform aggregate
> operations (e.g. using Diffie-Hellman to negotiate an HMAC). Operation
> is intended to be flexible, with support for input and output (where
> warranted) forms like big integers and binary.
>
> Please refer to Use Cases for additional API overviews.
> {zone-data}
>
> {zone-data:milestones}
> * Milestone 1: Implement Hashed-Message-Authentication-Code (HMAC) and
> Diffie-Hellman-Key-Exchange (DH)
> * Milestone 2: Verify operation using Unit Tests based on RFC test
> examples and which test both standard and binary output.
> * Milestone 3: Documentation
> {zone-data}
>
> {zone-data:class-list}
> * Zend_Crypt_Hmac
> * Zend_Crypt_DiffieHellman
> * Zend_Crypt_Math
> {zone-data}
>
> {zone-data:use-cases}
> * All use cases take the form of Unit Tests*
>
> * Zend_Crypt_Hmac *
>
> {code:php}
> class Zend_Crypt_HmacTest extends PHPUnit_Framework_TestCase
> {
>
> public function testHmacMD5_1()
> {
> $data = 'Hi There';
> $key = str_repeat("\x0b", 16);
> $hmac = new Zend_Crypt_Hmac($key, 'MD5');
> $this->assertEquals('9294727a3638bb1c13f48ef8158bfc9d',
> $hmac->hash($data));
> }
>
> public function testHmacSHA1_4()
> {
> $data = str_repeat("\xcd",50);
> $key =
> "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19";
> $hmac = new Zend_Crypt_Hmac($key, 'SHA1');
> $this->assertEquals('4c9007f4026250c6bc8414f9bf50c86c2d7235da',
> $hmac->hash($data));
> }
>
> public function testHmacRIPEMD160_6()
> {
> $data = 'Test Using Larger Than Block-Size Key - Hash Key First';
> $key = str_repeat("\xaa",80);
> $hmac = new Zend_Crypt_Hmac($key, 'RIPEMD160');
> $this->assertEquals('6466ca07ac5eac29e1bd523e5ada7605b791fd8b',
> $hmac->hash($data));
> }
>
> }
> {code}
>
> Please note that these simple Unit Tests are matched with far more
> realistic tests using big integers. The above are simple test cases used
> for illustrative purposes.
>
> * Zend_Crypt_DiffieHellman *
>
> Diffie-Hellman Key Exchange involved two parties, communicating across
> an insecure communication channel, negotiating a shared secret key which
> cannot be guessed or reverse engineered by a third party. If it looks a
> bit unintuitive - bear in mind the private keys are never exchanged.
> Without the private keys, a third party can have every single piece of
> data but remain unable to re-perform the shared key computation.
>
> {code:php}
> class Zend_Crypt_DiffieHellmanTest extends PHPUnit_Framework_TestCase
> {
>
> public function testDiffieWithSpec()
> {
> $aliceOptions = array(
> 'prime'=>'563',
> 'generator'=>'5',
> 'private'=>'9'
> );
> $bobOptions = array(
> 'prime'=>'563',
> 'generator'=>'5',
> 'private'=>'14'
> );
> $alice = new Zend_Crypt_DiffieHellman($aliceOptions['prime'],
> $aliceOptions['generator'], $aliceOptions['private']);
> $bob = new Zend_Crypt_DiffieHellman($bobOptions['prime'],
> $bobOptions['generator'], $bobOptions['private']);
> $alice->generateKeys();
> $bob->generateKeys();
>
> $this->assertEquals('78', $alice->getPublicKey());
> $this->assertEquals('534', $bob->getPublicKey());
>
> $aliceSecretKey =
> $alice->computeSecretKey($bob->getPublicKey())->getSharedSecretKey();
> $bobSecretKey =
> $bob->computeSecretKey($alice->getPublicKey())->getSharedSecretKey();
>
> // both Alice and Bob should now have the same secret key
> $this->assertEquals('117', $aliceSecretKey);
> $this->assertEquals('117', $bobSecretKey);
> }
>
> }
> {code}
>
> Please note that these simple Unit Tests are matched with far more
> realistic tests using big integers. The above are simple test cases used
> for illustrative purposes.
> {zone-data}
>
> {zone-data:skeletons}
> *Zend_Crypt_Hmac*
>
> {code:php}
> /**
> * PHP implementation of the RFC 2104 Hash based Message Authentication Code
> * algorithm.
> *
> * @category Zend
> * @package Zend_Crypt
> * @copyright Copyright (c) 2007 Pádraic Brady
> (http://blog.astrumfutura.com)
> * @license http://framework.zend.com/license/new-bsd New BSD License
> * @todo Check if mhash() is a required alternative (will be
> PECL-only soon)
> */
> class Zend_Crypt_Hmac
> {
>
> /**
> * The key to use for the hash
> *
> * @var string
> */
> private $_key = null;
>
> /**
> * pack() format to be used for current hashing method
> *
> * @var string
> */
> private $_packFormat = null;
>
> /**
> * Hashing algorithm; can be the md5/sha1 functions or any algorithm
> name
> * listed in the output of PHP 5.1.2+ hash_algos().
> *
> * @var string
> */
> private $_hashAlgorithm = 'md5';
>
> /**
> * Supported direct hashing functions in PHP
> *
> * @var array
> */
> private $_supportedHashNativeFunctions = array(
> 'md5',
> 'sha1',
> );
>
> /**
> * List of hash pack formats for each hashing algorithm supported.
> * Only required when hash or mhash are not available, and we are
> * using either md5() or sha1().
> *
> * @var array
> */
> private $_hashPackFormats = array(
> 'md5' => 'H32',
> 'sha1' => 'H40'
> );
>
> /**
> * List of algorithms supported my mhash()
> *
> * @var array
> */
> private $_supportedMhashAlgorithms = array('adler32',' crc32',
> 'crc32b', 'gost',
> 'haval128', 'haval160', 'haval192', 'haval256', 'md4',
> 'md5', 'ripemd160',
> 'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160');
>
> /**
> * Constants representing the output mode of the hash algorithm
> */
> const STRING = 'string';
> const BINARY = 'binary';
>
> /**
> * Constructor; optionally set Key and Hash at this point
> *
> * @param string $key
> * @param string $hash
> * @return void
> */
> public function __construct($key = null, $hash = null)
> {}
>
> /**
> * Set the key to use when hashing
> *
> * @param string $key
> * @return Zend_Crypt_Hmac
> */
> public function setKey($key)
> {}
>
> /**
> * Getter to return the currently set key
> *
> * @return string
> */
> public function getKey()
> {}
>
> /**
> * Setter for the hash method. Supports md5() and sha1() functions,
> and if
> * available the hashing algorithms supported by the hash() PHP5
> function.
> *
> * @param string $hash
> * @return Zend_Crypt_Hmac
> */
> public function setHashAlgorithm($hash)
> {}
>
> /**
> * Return the current hashing algorithm
> *
> * @return string
> */
> public function getHashAlgorithm()
> {}
>
> /**
> * Perform HMAC and return the keyed data
> *
> * @param string $data
> * @param string $output
> * @param bool $internal Option to not use hash() functions for testing
> * @return string
> */
> public function hash($data, $output = self::STRING, $internal = false)
> {}
>
> /**
> * Since MHASH accepts an integer constant representing the hash
> algorithm
> * we need to make a small detour to get the correct integer
> matching our
> * algorithm's name.
> *
> * @param string $hashAlgorithm
> * @return integer
> */
> protected function _getMhashDefinition($hashAlgorithm)
> {}
>
> /**
> * Digest method when using native functions which allows the selection
> * of raw binary output.
> *
> * @param string $hash
> * @param string $key
> * @param string $mode
> * @return string
> */
> protected function _digest($hash, $key, $mode)
> {}
>
> }
> {code}
>
> *Zend_Crypt_DiffieHellman*
>
> {code:php}
> /**
> * PHP implementation of the Diffie-Hellman public key encryption algorithm.
> * Allows two unassociated parties to establish a joint shared secret key
> * to be used in encrypting subsequent communications.
> *
> * @category Zend
> * @package Zend_Crypt
> * @subpackage DiffieHellman
> * @copyright Copyright (c) 2007 Pádraic Brady
> (http://blog.astrumfutura.com)
> * @license http://framework.zend.com/license/new-bsd New BSD License
> */
> class Zend_Crypt_DiffieHellman
> {
>
> /**
> * Default large prime number; required by the algorithm.
> *
> * @var string
> */
> private $_prime = null;
>
> /**
> * The default generator number. This number must be greater than 0 but
> * less than the prime number set.
> *
> * @var string
> */
> private $_generator = null;
>
> /**
> * A private number set by the local user. It's optional and will
> * be generated if not set.
> *
> * @var string
> */
> private $_privateKey = null;
>
> /**
> * BigInteger support object courtesy of Zend_Math
> *
> * @var Zend_Math_BigInteger
> */
> private $_math = null;
>
> /**
> * The public key generated by this instance after calling
> generateKeys().
> *
> * @var string
> */
> private $_publicKey = null;
>
> /**
> * The shared secret key resulting from a completed Diffie Hellman
> * exchange
> *
> * @var string
> */
> private $_secretKey = null;
>
> /**
> * Constants
> */
> const BINARY = 'binary';
> const NUMBER = 'number';
> const BTWOC = 'btwoc';
>
> /**
> * Constructor; if set construct the object using the parameter array to
> * set values for Prime, Generator and Private.
> * If a Private Key is not set, one will be generated at random.
> *
> * @param string $prime
> * @param string $generator
> * @param string $privateKey
> * @param string $privateKeyType
> * @return void
> */
> public function __construct($prime, $generator, $privateKey = null,
> $privateKeyType = self::NUMBER)
> {}
>
> /**
> * Generate own public key. If a private number has not already been
> * set, one will be generated at this stage.
> *
> * @return Zend_Crypt_DiffieHellman
> */
> public function generateKeys()
> {}
>
> /**
> * Returns own public key for communication to the second party to this
> * transaction.
> *
> * @param string $type
> * @return string
> */
> public function getPublicKey($type = self::NUMBER)
> {}
>
> /**
> * Compute the shared secret key based on the public key received
> from the
> * the second party to this transaction. This should agree to the secret
> * key the second party computes on our own public key.
> * Once in agreement, the key is known to only to both parties.
> * By default, the function expects the public key to be in binary form
> * which is the typical format when being transmitted.
> *
> * @param string $publicKey
> * @param string $type
> * @return Zend_Crypt_DiffieHellman
> */
> public function computeSecretKey($publicKey, $type = self::NUMBER)
> {}
>
> /**
> * Return the computed shared secret key from the DiffieHellman
> transaction
> *
> * @param string $type
> * @return string
> */
> public function getSharedSecretKey($type = self::NUMBER)
> {}
>
> /**
> * Setter for the value of the prime number
> *
> * @param string $number
> * @return Zend_Crypt_DiffieHellman
> */
> public function setPrime($number)
> {}
>
> /**
> * Getter for the value of the prime number
> *
> * @return string
> */
> public function getPrime()
> {}
>
>
> /**
> * Setter for the value of the generator number
> *
> * @param string $number
> * @return Zend_Crypt_DiffieHellman
> */
> public function setGenerator($number)
> {}
>
> /**
> * Getter for the value of the generator number
> *
> * @return string
> */
> public function getGenerator()
> {}
>
> /**
> * Setter for the value of the private number
> *
> * @param string $number
> * @param string $type
> * @return Zend_Crypt_DiffieHellman
> */
> public function setPrivateKey($number, $type = self::NUMBER)
> {}
>
> /**
> * Getter for the value of the private number
> *
> * @param string $type
> * @return string
> */
> public function getPrivateKey($type = self::NUMBER)
> {}
>
> /**
> * Setter to pass an extension parameter which is used to create
> * a specific BigInteger instance for a specific extension type.
> * Allows manual setting of the class in case of an extension
> * problem or bug.
> *
> * @param string $extension
> * @return void
> */
> public function setBigIntegerMath($extension = null)
> {}
>
> /**
> * In the event a private number/key has not been set by the user,
> * generate one at random.
> *
> * @return string
> */
> protected function _generatePrivateKey()
> {}
>
> }
> {code}
> {zone-data}
>
> {zone-template-instance}
>
> Pádraic Brady
> http://blog.astrumfutura.com
> http://www.patternsforphp.com
>
>
> ------------------------------------------------------------------------
> Be a better Heartthrob. Get better relationship answers
> <http://us.rd.yahoo.com/evt=48255/*http://answers.yahoo.com/dir/_ylc=X3oDMTI5MGx2aThyBF9TAzIxMTU1MDAzNTIEX3MDMzk2NTQ1MTAzBHNlYwNCQUJwaWxsYXJfTklfMzYwBHNsawNQcm9kdWN0X3F1ZXN0aW9uX3BhZ2U-?link=list&sid=396545433>from
> someone who knows.
> Yahoo! Answers - Check it out.