SecurityTest.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  12. * @since 1.2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Utility;
  16. use Cake\TestSuite\TestCase;
  17. use Cake\Utility\Security;
  18. /**
  19. * SecurityTest class
  20. *
  21. */
  22. class SecurityTest extends TestCase {
  23. /**
  24. * testGenerateAuthkey method
  25. *
  26. * @return void
  27. */
  28. public function testGenerateAuthkey() {
  29. $this->assertEquals(strlen(Security::generateAuthKey()), 40);
  30. }
  31. /**
  32. * testHash method
  33. *
  34. * @return void
  35. */
  36. public function testHash() {
  37. $_hashType = Security::$hashType;
  38. $key = 'someKey';
  39. $hash = 'someHash';
  40. $this->assertSame(40, strlen(Security::hash($key, null, false)));
  41. $this->assertSame(40, strlen(Security::hash($key, 'sha1', false)));
  42. $this->assertSame(40, strlen(Security::hash($key, null, true)));
  43. $this->assertSame(40, strlen(Security::hash($key, 'sha1', true)));
  44. $result = Security::hash($key, null, $hash);
  45. $this->assertSame($result, 'e38fcb877dccb6a94729a81523851c931a46efb1');
  46. $result = Security::hash($key, 'sha1', $hash);
  47. $this->assertSame($result, 'e38fcb877dccb6a94729a81523851c931a46efb1');
  48. $hashType = 'sha1';
  49. Security::setHash($hashType);
  50. $this->assertSame($hashType, Security::$hashType);
  51. $this->assertSame(40, strlen(Security::hash($key, null, true)));
  52. $this->assertSame(40, strlen(Security::hash($key, null, false)));
  53. $this->assertSame(32, strlen(Security::hash($key, 'md5', false)));
  54. $this->assertSame(32, strlen(Security::hash($key, 'md5', true)));
  55. $hashType = 'md5';
  56. Security::setHash($hashType);
  57. $this->assertSame($hashType, Security::$hashType);
  58. $this->assertSame(32, strlen(Security::hash($key, null, false)));
  59. $this->assertSame(32, strlen(Security::hash($key, null, true)));
  60. $this->assertSame(64, strlen(Security::hash($key, 'sha256', false)));
  61. $this->assertSame(64, strlen(Security::hash($key, 'sha256', true)));
  62. Security::setHash($_hashType);
  63. }
  64. /**
  65. * testRijndael method
  66. *
  67. * @return void
  68. */
  69. public function testRijndael() {
  70. $this->skipIf(!function_exists('mcrypt_encrypt'));
  71. $txt = 'The quick brown fox jumped over the lazy dog.';
  72. $key = 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi';
  73. $result = Security::rijndael($txt, $key, 'encrypt');
  74. $this->assertEquals($txt, Security::rijndael($result, $key, 'decrypt'));
  75. $result = Security::rijndael($key, $txt, 'encrypt');
  76. $this->assertEquals($key, Security::rijndael($result, $txt, 'decrypt'));
  77. $result = Security::rijndael('', $key, 'encrypt');
  78. $this->assertEquals('', Security::rijndael($result, $key, 'decrypt'));
  79. $key = 'this is my key of over 32 chars, yes it is';
  80. $result = Security::rijndael($txt, $key, 'encrypt');
  81. $this->assertEquals($txt, Security::rijndael($result, $key, 'decrypt'));
  82. }
  83. /**
  84. * testRijndaelInvalidOperation method
  85. *
  86. * @expectedException \InvalidArgumentException
  87. * @return void
  88. */
  89. public function testRijndaelInvalidOperation() {
  90. $txt = 'The quick brown fox jumped over the lazy dog.';
  91. $key = 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi';
  92. Security::rijndael($txt, $key, 'foo');
  93. }
  94. /**
  95. * testRijndaelInvalidKey method
  96. *
  97. * @expectedException \InvalidArgumentException
  98. * @return void
  99. */
  100. public function testRijndaelInvalidKey() {
  101. $txt = 'The quick brown fox jumped over the lazy dog.';
  102. $key = 'too small';
  103. Security::rijndael($txt, $key, 'encrypt');
  104. }
  105. /**
  106. * Test encrypt/decrypt.
  107. *
  108. * @return void
  109. */
  110. public function testEncryptDecrypt() {
  111. $txt = 'The quick brown fox';
  112. $key = 'This key is longer than 32 bytes long.';
  113. $result = Security::encrypt($txt, $key);
  114. $this->assertNotEquals($txt, $result, 'Should be encrypted.');
  115. $this->assertNotEquals($result, Security::encrypt($txt, $key), 'Each result is unique.');
  116. $this->assertEquals($txt, Security::decrypt($result, $key));
  117. }
  118. /**
  119. * Test that changing the key causes decryption to fail.
  120. *
  121. * @return void
  122. */
  123. public function testDecryptKeyFailure() {
  124. $txt = 'The quick brown fox';
  125. $key = 'This key is longer than 32 bytes long.';
  126. $result = Security::encrypt($txt, $key);
  127. $key = 'Not the same key. This one will fail';
  128. $this->assertFalse(Security::decrypt($txt, $key), 'Modified key will fail.');
  129. }
  130. /**
  131. * Test that decrypt fails when there is an hmac error.
  132. *
  133. * @return void
  134. */
  135. public function testDecryptHmacFailure() {
  136. $txt = 'The quick brown fox';
  137. $key = 'This key is quite long and works well.';
  138. $salt = 'this is a delicious salt!';
  139. $result = Security::encrypt($txt, $key, $salt);
  140. // Change one of the bytes in the hmac.
  141. $result[10] = 'x';
  142. $this->assertFalse(Security::decrypt($result, $key, $salt), 'Modified hmac causes failure.');
  143. }
  144. /**
  145. * Test that changing the hmac salt will cause failures.
  146. *
  147. * @return void
  148. */
  149. public function testDecryptHmacSaltFailure() {
  150. $txt = 'The quick brown fox';
  151. $key = 'This key is quite long and works well.';
  152. $salt = 'this is a delicious salt!';
  153. $result = Security::encrypt($txt, $key, $salt);
  154. $salt = 'humpty dumpty had a great fall.';
  155. $this->assertFalse(Security::decrypt($result, $key, $salt), 'Modified salt causes failure.');
  156. }
  157. /**
  158. * Test that short keys cause errors
  159. *
  160. * @expectedException \InvalidArgumentException
  161. * @expectedExceptionMessage Invalid key for encrypt(), key must be at least 256 bits (32 bytes) long.
  162. * @return void
  163. */
  164. public function testEncryptInvalidKey() {
  165. $txt = 'The quick brown fox jumped over the lazy dog.';
  166. $key = 'this is too short';
  167. Security::encrypt($txt, $key);
  168. }
  169. /**
  170. * Test encrypting falsey data
  171. *
  172. * @return void
  173. */
  174. public function testEncryptDecryptFalseyData() {
  175. $key = 'This is a key that is long enough to be ok.';
  176. $result = Security::encrypt('', $key);
  177. $this->assertSame('', Security::decrypt($result, $key));
  178. $result = Security::encrypt(false, $key);
  179. $this->assertSame('', Security::decrypt($result, $key));
  180. $result = Security::encrypt(null, $key);
  181. $this->assertSame('', Security::decrypt($result, $key));
  182. $result = Security::encrypt(0, $key);
  183. $this->assertSame('0', Security::decrypt($result, $key));
  184. $result = Security::encrypt('0', $key);
  185. $this->assertSame('0', Security::decrypt($result, $key));
  186. }
  187. /**
  188. * Test that short keys cause errors
  189. *
  190. * @expectedException \InvalidArgumentException
  191. * @expectedExceptionMessage Invalid key for decrypt(), key must be at least 256 bits (32 bytes) long.
  192. * @return void
  193. */
  194. public function testDecryptInvalidKey() {
  195. $txt = 'The quick brown fox jumped over the lazy dog.';
  196. $key = 'this is too short';
  197. Security::decrypt($txt, $key);
  198. }
  199. /**
  200. * Test that empty data cause errors
  201. *
  202. * @expectedException \InvalidArgumentException
  203. * @expectedExceptionMessage The data to decrypt cannot be empty.
  204. * @return void
  205. */
  206. public function testDecryptInvalidData() {
  207. $txt = '';
  208. $key = 'This is a key that is long enough to be ok.';
  209. Security::decrypt($txt, $key);
  210. }
  211. /**
  212. * Tests that the salt can be set and retrieved
  213. *
  214. * @return void
  215. */
  216. public function testSalt() {
  217. Security::salt('foobarbaz');
  218. $this->assertEquals('foobarbaz', Security::salt());
  219. }
  220. }