crypto.php 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. class Crypto
  3. {
  4. const METHOD = 'aes-256-ctr';
  5. public function encrypt($plaintext, $password, $salt='', $encode = false)
  6. {
  7. $keyAndIV = self::evpKDF($password, $salt);
  8. $ciphertext = openssl_encrypt(
  9. $plaintext,
  10. self::METHOD,
  11. $keyAndIV["key"],
  12. OPENSSL_RAW_DATA,
  13. $keyAndIV["iv"]
  14. );
  15. $ciphertext = bin2hex($ciphertext);
  16. if ($encode)
  17. {
  18. $ciphertext = base64_encode($ciphertext);
  19. }
  20. return $ciphertext;
  21. }
  22. public function decrypt($ciphertext, $password, $salt='', $encoded = false)
  23. {
  24. if ( $encoded )
  25. {
  26. $ciphertext = base64_decode($ciphertext, true);
  27. if ($ciphertext === false)
  28. {
  29. throw new Exception('Encryption failure');
  30. }
  31. }
  32. $ciphertext = hex2bin($ciphertext);
  33. $keyAndIV = self::evpKDF($password, $salt);
  34. $plaintext = openssl_decrypt(
  35. $ciphertext,
  36. self::METHOD,
  37. $keyAndIV["key"],
  38. OPENSSL_RAW_DATA,
  39. $keyAndIV["iv"]
  40. );
  41. return $plaintext;
  42. }
  43. public function evpKDF($password, $salt, $keySize = 8, $ivSize = 4, $iterations = 1, $hashAlgorithm = "md5")
  44. {
  45. $targetKeySize = $keySize + $ivSize;
  46. $derivedBytes = "";
  47. $numberOfDerivedWords = 0;
  48. $block = NULL;
  49. $hasher = hash_init($hashAlgorithm);
  50. while ($numberOfDerivedWords < $targetKeySize)
  51. {
  52. if ($block != NULL)
  53. {
  54. hash_update($hasher, $block);
  55. }
  56. hash_update($hasher, $password);
  57. hash_update($hasher, $salt);
  58. $block = hash_final($hasher, TRUE);
  59. $hasher = hash_init($hashAlgorithm);
  60. // Iterations
  61. for ($i = 1; $i < $iterations; $i++)
  62. {
  63. hash_update($hasher, $block);
  64. $block = hash_final($hasher, TRUE);
  65. $hasher = hash_init($hashAlgorithm);
  66. }
  67. $derivedBytes .= substr($block, 0, min(strlen($block), ($targetKeySize - $numberOfDerivedWords) * 4));
  68. $numberOfDerivedWords += strlen($block)/4;
  69. }
  70. return array(
  71. "key" => substr($derivedBytes, 0, $keySize * 4),
  72. "iv" => substr($derivedBytes, $keySize * 4, $ivSize * 4)
  73. );
  74. }
  75. }
  76. ?>