CryptorTest.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. namespace RNCryptor;
  3. class CryptorTest extends \PHPUnit_Framework_TestCase {
  4. // relative to __DIR__
  5. const TEXT_FILENAME = 'lorem-ipsum.txt';
  6. const SAMPLE_PLAINTEXT = 'What\'s your name? My name is Tilgath Pilesar. Why are you crying?';
  7. const SAMPLE_PASSWORD = 'do-not-write-this-down';
  8. const SAMPLE_PLAINTEXT_V2_BLOCKSIZE = 'Lorem ipsum dolor sit amet, cons';
  9. public static function main() {
  10. $suite = new PHPUnit_Framework_TestSuite(get_called_class());
  11. $result = PHPUnit_TextUI_TestRunner::run($suite);
  12. }
  13. public function testCanDecryptSelfEncryptedDefaultVersion() {
  14. $encryptor = new Encryptor();
  15. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, self::SAMPLE_PASSWORD);
  16. $decryptor = new Decryptor();
  17. $decrypted = $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  18. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  19. }
  20. public function testCanDecryptSelfEncryptedStringEqualToBlockSizeMultiple() {
  21. $encryptor = new Encryptor();
  22. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT_V2_BLOCKSIZE, self::SAMPLE_PASSWORD);
  23. $decryptor = new Decryptor();
  24. $decrypted = $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  25. $this->assertEquals(self::SAMPLE_PLAINTEXT_V2_BLOCKSIZE, $decrypted);
  26. }
  27. public function testCanDecryptSelfEncryptedVersion0() {
  28. $encryptor = new Encryptor();
  29. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, self::SAMPLE_PASSWORD, 0);
  30. $decryptor = new Decryptor();
  31. $decrypted = $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  32. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  33. }
  34. public function testCanDecryptSelfEncryptedVersion1() {
  35. $encryptor = new Encryptor();
  36. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, self::SAMPLE_PASSWORD, 1);
  37. $decryptor = new Decryptor();
  38. $decrypted = $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  39. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  40. }
  41. public function testCanDecryptSelfEncryptedVersion2() {
  42. $encryptor = new Encryptor();
  43. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, self::SAMPLE_PASSWORD, 2);
  44. $decryptor = new Decryptor();
  45. $decrypted = $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  46. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  47. }
  48. public function testCanDecryptLongText() {
  49. $text = file_get_contents(__DIR__ . '/_files/lorem-ipsum.txt');
  50. $encryptor = new Encryptor();
  51. $encrypted = $encryptor->encrypt($text, self::SAMPLE_PASSWORD);
  52. $decryptor = new Decryptor();
  53. $decrypted = $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  54. $this->assertEquals($text, $decrypted);
  55. }
  56. public function testVersion1TruncatesMultibytePasswords() {
  57. $password1 = '中文密码';
  58. $encryptor = new Encryptor();
  59. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, $password1, 1);
  60. // Yikes, it's truncated! So with an all-multibyte password
  61. // like above, we can replace the last half of the string
  62. // with whatver we want, and decryption will still work.
  63. $password2 = '中文中文';
  64. $decryptor = new Decryptor();
  65. $decrypted = $decryptor->decrypt($encrypted, $password2);
  66. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  67. $decryptor = new Decryptor();
  68. $decrypted = $decryptor->decrypt($encrypted, $password1);
  69. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  70. }
  71. public function testVersion2TruncatesMultibytePasswords() {
  72. $password1 = '中文密码';
  73. $encryptor = new Encryptor();
  74. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, $password1, 2);
  75. // Yikes, it's truncated! So with an all-multibyte password
  76. // like above, we can replace the last half of the string
  77. // with whatver we want, and decryption will still work.
  78. $password2 = '中文中文';
  79. $decryptor = new Decryptor();
  80. $decrypted = $decryptor->decrypt($encrypted, $password2);
  81. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  82. $decryptor = new Decryptor();
  83. $decrypted = $decryptor->decrypt($encrypted, $password1);
  84. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  85. }
  86. public function testVersion3AcceptsMultibytePasswords() {
  87. $password1 = '中文密码';
  88. $encryptor = new Encryptor();
  89. $encrypted = $encryptor->encrypt(self::SAMPLE_PLAINTEXT, $password1, 3);
  90. $password2 = '中文中文';
  91. $decryptor = new Decryptor();
  92. $decrypted = $decryptor->decrypt($encrypted, $password2);
  93. $this->assertFalse($decrypted);
  94. $decryptor = new Decryptor();
  95. $decrypted = $decryptor->decrypt($encrypted, $password1);
  96. $this->assertEquals(self::SAMPLE_PLAINTEXT, $decrypted);
  97. }
  98. public function testCannotUseWithUnsupportedSchemaVersions() {
  99. $fakeSchemaNumber = 57;
  100. $encrypted = $this->_generateEncryptedStringWithUnsupportedSchemaNumber($fakeSchemaNumber);
  101. $decryptor = new Decryptor();
  102. $this->setExpectedException('Exception');
  103. $decryptor->decrypt($encrypted, self::SAMPLE_PASSWORD);
  104. }
  105. private function _generateEncryptedStringWithUnsupportedSchemaNumber($fakeSchemaNumber) {
  106. $encryptor = new Encryptor();
  107. $plaintext = 'The price of ice is nice for mice';
  108. $encrypted = $encryptor->encrypt($plaintext, self::SAMPLE_PASSWORD);
  109. $encryptedBinary = base64_decode($encrypted);
  110. $encryptedBinary = chr($fakeSchemaNumber) . substr($encryptedBinary, 1, strlen($encryptedBinary - 1));
  111. return base64_encode($encryptedBinary);
  112. }
  113. }