fork(1) download
  1. <?php
  2.  
  3. class EncryptorClass
  4. {
  5. protected static $public_key;
  6. protected static $private_key;
  7.  
  8. const KEYS_DIR = __DIR__ . '/dir/dir/dir/keys';
  9. const KEY_PASSPHRASE = 'bla-bla-bla';
  10.  
  11. const MAX_DATA_LENGTH = 128;
  12. const DECRYPT_CHUNK_SIZE = 256;
  13.  
  14. public static function encode($data)
  15. {
  16. if (is_numeric($data) === false && is_string($data) === false) {
  17. $data = json_encode($data);
  18. }
  19.  
  20. $encrypted = null;
  21.  
  22. // разбитие больших данных на куски
  23. if (strlen($data) > self::MAX_DATA_LENGTH) {
  24. $data = str_split($data, self::MAX_DATA_LENGTH);
  25. } else {
  26. $data = [$data];
  27. }
  28. $encrypt_result = true;
  29. foreach ($data as $chunk) {
  30. $encrypt_result = openssl_public_encrypt($chunk, $encrypted_chunk, self::$public_key);
  31. if ($encrypt_result === false) {
  32. break;
  33. }
  34.  
  35. $encrypted .= $encrypted_chunk;
  36. }
  37. if ($encrypt_result) {
  38. $encrypted = base64_encode($encrypted);
  39. } else {
  40. $errors = [];
  41. while($error = openssl_error_string()) {
  42. $errors[] = $error;
  43. }
  44.  
  45. $message = 'Не удалось зашифровать данные. ' . implode(" \n", $errors);
  46. error_log($message . "\n data: " . JSON::encode($data));
  47. throw new \Exception($message);
  48. }
  49.  
  50. return $encrypted;
  51. }
  52.  
  53. public static function decode(string $data, bool $jsonDecode = false)
  54. {
  55. /** @see https://s...content-available-to-author-only...p.net/manual/en/function.base64-decode.php#102113 */
  56. $encrypted = base64_decode(str_replace(' ', '+', $data));
  57.  
  58. if ($encrypted === false) {
  59. $encrypted = $data;
  60. }
  61.  
  62. $errors = [];
  63. $decrypted = null;
  64.  
  65. // попытка разблокировать данные как просто зашифрованную строку
  66. if (openssl_private_decrypt($encrypted, $decrypted, openssl_pkey_get_private(self::$private_key, self::KEY_PASSPHRASE)) === false) {
  67. // разбитие для расшифровки длинных зашифрованных строк
  68. $decrypted = null;
  69. $encrypted = str_split($encrypted, self::DECRYPT_CHUNK_SIZE);
  70. foreach ($encrypted as $chunk) {
  71. $decrypt_result = '';
  72. if (openssl_private_decrypt($chunk, $decrypt_result, openssl_pkey_get_private(self::$private_key, self::KEY_PASSPHRASE))) {
  73. $decrypted .= $decrypt_result;
  74. } else {
  75. while($error = openssl_error_string()) {
  76. $errors[] = $error;
  77. }
  78.  
  79. $message = 'Не удалось расшифровать данные. ' . implode(" \n", $errors);
  80. error_log($message . "\n data: " . JSON::encode($data));
  81. throw new \Exception($message);
  82. }
  83. }
  84. }
  85.  
  86. if ($jsonDecode && is_string($decrypted) && JSON::isValid($decrypted)) {
  87. $decrypted = JSON::decode($decrypted);
  88. }
  89.  
  90. return $decrypted;
  91. }
  92.  
  93. /**
  94.   * Ключи RSA сгенерированы командами с заданием пароля self::KEY_PASSPHRASE:
  95.   * openssl genrsa -des3 -out private_rsa.pem 2048
  96.   * openssl rsa -in private_rsa.pem -outform PEM -pubout -out public_rsa.pem
  97.   */
  98. public function __construct()
  99. {
  100. $public_key_path = realpath(self::KEYS_DIR . '/public_rsa.pem');
  101. $private_key_path = realpath(self::KEYS_DIR . '/private_rsa.pem');
  102.  
  103. self::$public_key = file_get_contents($public_key_path);
  104. self::$private_key = file_get_contents($private_key_path);
  105. }
  106. }
Success #stdin #stdout 0s 82560KB
stdin
Standard input is empty
stdout
Standard output is empty