Encryptor.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. namespace RNCryptor\RNCryptor;
  3. use stdClass;
  4. /**
  5. * RNEncryptor for PHP
  6. *
  7. * Encrypt data interchangeably with Rob Napier's Objective-C implementation
  8. * of RNCryptor
  9. */
  10. class Encryptor extends Cryptor
  11. {
  12. /**
  13. * Encrypt plaintext using RNCryptor's algorithm
  14. *
  15. * @param string $plaintext Text to be encrypted
  16. * @param string $password Password to use
  17. * @param int $version (Optional) RNCryptor schema version to use.
  18. * @throws \Exception If the provided version (if any) is unsupported
  19. * @return string Encrypted, Base64-encoded string
  20. */
  21. public function encrypt($plaintext, $password, $version = Cryptor::DEFAULT_SCHEMA_VERSION)
  22. {
  23. $this->configure($version);
  24. $components = $this->makeComponents($version);
  25. $components->headers->encSalt = $this->makeSalt();
  26. $components->headers->hmacSalt = $this->makeSalt();
  27. $components->headers->iv = $this->makeIv($this->config->ivLength);
  28. $encKey = $this->makeKey($components->headers->encSalt, $password);
  29. $hmacKey = $this->makeKey($components->headers->hmacSalt, $password);
  30. return $this->encryptFromComponents($plaintext, $components, $encKey, $hmacKey);
  31. }
  32. public function encryptWithArbitrarySalts(
  33. $plaintext,
  34. $password,
  35. $encSalt,
  36. $hmacSalt,
  37. $iv,
  38. $version = Cryptor::DEFAULT_SCHEMA_VERSION
  39. ) {
  40. $this->configure($version);
  41. $components = $this->makeComponents($version);
  42. $components->headers->encSalt = $encSalt;
  43. $components->headers->hmacSalt = $hmacSalt;
  44. $components->headers->iv = $iv;
  45. $encKey = $this->makeKey($components->headers->encSalt, $password);
  46. $hmacKey = $this->makeKey($components->headers->hmacSalt, $password);
  47. return $this->encryptFromComponents($plaintext, $components, $encKey, $hmacKey);
  48. }
  49. public function encryptWithArbitraryKeys(
  50. $plaintext,
  51. $encKey,
  52. $hmacKey,
  53. $iv,
  54. $version = Cryptor::DEFAULT_SCHEMA_VERSION
  55. ) {
  56. $this->configure($version);
  57. $this->config->options = 0;
  58. $components = $this->makeComponents($version);
  59. $components->headers->iv = $iv;
  60. return $this->encryptFromComponents($plaintext, $components, $encKey, $hmacKey);
  61. }
  62. private function makeComponents($version)
  63. {
  64. $components = new stdClass;
  65. $components->headers = new stdClass;
  66. $components->headers->version = chr($version);
  67. $components->headers->options = chr($this->config->options);
  68. return $components;
  69. }
  70. private function encryptFromComponents($plaintext, stdClass $components, $encKey, $hmacKey)
  71. {
  72. $iv = $components->headers->iv;
  73. if ($this->config->mode == 'ctr') {
  74. $components->ciphertext = $this->aesCtrLittleEndianCrypt($plaintext, $encKey, $iv);
  75. } else {
  76. $components->ciphertext = $this->encryptInternal($encKey, $plaintext, 'cbc', $iv);
  77. }
  78. return base64_encode(''
  79. . $components->headers->version
  80. . $components->headers->options
  81. . ($components->headers->encSalt ?? '')
  82. . ($components->headers->hmacSalt ?? '')
  83. . $components->headers->iv
  84. . $components->ciphertext
  85. . $this->makeHmac($components, $hmacKey));
  86. }
  87. private function makeSalt()
  88. {
  89. return $this->makeIv($this->config->saltLength);
  90. }
  91. private function makeIv($blockSize)
  92. {
  93. return openssl_random_pseudo_bytes($blockSize);
  94. }
  95. }