Encryptor.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. namespace RNCryptor;
  3. /**
  4. * RNEncryptor for PHP
  5. *
  6. * Encrypt data interchangeably with Rob Napier's Objective-C implementation
  7. * of RNCryptor
  8. */
  9. class Encryptor extends Cryptor {
  10. /**
  11. * Encrypt plaintext using RNCryptor's algorithm
  12. *
  13. * @param string $plaintext Text to be encrypted
  14. * @param string $password Password to use
  15. * @param int $version (Optional) RNCryptor schema version to use.
  16. * @throws \Exception If the provided version (if any) is unsupported
  17. * @return string Encrypted, Base64-encoded string
  18. */
  19. public function encrypt($plaintext, $password, $version = Cryptor::DEFAULT_SCHEMA_VERSION) {
  20. $this->_configureSettings($version);
  21. $components = $this->_generateInitializedComponents($version);
  22. $components->headers->encSalt = $this->_generateSalt();
  23. $components->headers->hmacSalt = $this->_generateSalt();
  24. $components->headers->iv = $this->_generateIv($this->_settings->ivLength);
  25. $encKey = $this->_generateKey($components->headers->encSalt, $password);
  26. $hmacKey = $this->_generateKey($components->headers->hmacSalt, $password);
  27. return $this->_encrypt($plaintext, $components, $encKey, $hmacKey);
  28. }
  29. public function encryptWithArbitrarySalts($plaintext, $password, $encSalt, $hmacSalt, $iv, $version = Cryptor::DEFAULT_SCHEMA_VERSION) {
  30. $this->_configureSettings($version);
  31. $components = $this->_generateInitializedComponents($version);
  32. $components->headers->encSalt = $encSalt;
  33. $components->headers->hmacSalt = $hmacSalt;
  34. $components->headers->iv = $iv;
  35. $encKey = $this->_generateKey($components->headers->encSalt, $password);
  36. $hmacKey = $this->_generateKey($components->headers->hmacSalt, $password);
  37. return $this->_encrypt($plaintext, $components, $encKey, $hmacKey);
  38. }
  39. public function encryptWithArbitraryKeys($plaintext, $encKey, $hmacKey, $iv, $version = Cryptor::DEFAULT_SCHEMA_VERSION) {
  40. $this->_configureSettings($version);
  41. $this->_settings->options = 0;
  42. $components = $this->_generateInitializedComponents($version);
  43. $components->headers->iv = $iv;
  44. return $this->_encrypt($plaintext, $components, $encKey, $hmacKey);
  45. }
  46. private function _generateInitializedComponents($version) {
  47. $components = new \stdClass();
  48. $components->headers = new \stdClass();
  49. $components->headers->version = chr($version);
  50. $components->headers->options = chr($this->_settings->options);
  51. return $components;
  52. }
  53. private function _encrypt($plaintext, \stdClass $components, $encKey, $hmacKey) {
  54. switch ($this->_settings->mode) {
  55. case 'ctr':
  56. $components->ciphertext = $this->_aesCtrLittleEndianCrypt($plaintext, $encKey, $components->headers->iv);
  57. break;
  58. case 'cbc':
  59. $paddedPlaintext = $this->_addPKCS7Padding($plaintext, strlen($components->headers->iv));
  60. $components->ciphertext = mcrypt_encrypt($this->_settings->algorithm, $encKey, $paddedPlaintext, 'cbc', $components->headers->iv);
  61. break;
  62. }
  63. $binaryData = ''
  64. . $components->headers->version
  65. . $components->headers->options
  66. . (isset($components->headers->encSalt) ? $components->headers->encSalt : '')
  67. . (isset($components->headers->hmacSalt) ? $components->headers->hmacSalt : '')
  68. . $components->headers->iv
  69. . $components->ciphertext;
  70. $hmac = $this->_generateHmac($components, $hmacKey);
  71. return base64_encode($binaryData . $hmac);
  72. }
  73. private function _addPKCS7Padding($plaintext, $blockSize) {
  74. $padSize = $blockSize - (strlen($plaintext) % $blockSize);
  75. return $plaintext . str_repeat(chr($padSize), $padSize);
  76. }
  77. private function _generateSalt() {
  78. return $this->_generateIv($this->_settings->saltLength);
  79. }
  80. private function _generateIv($blockSize) {
  81. if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
  82. $randomSource = MCRYPT_RAND;
  83. } else {
  84. $randomSource = MCRYPT_DEV_URANDOM;
  85. }
  86. return mcrypt_create_iv($blockSize, $randomSource);
  87. }
  88. }