Как шифровать данные в php с помощью общедоступных / закрытых ключей?

У меня есть небольшая строка некоторых данных (менее 1 КБ), которые я бы хотел, чтобы пользовательские агенты переходили на другие сайты, когда они отправляются с моего сайта. Чтобы другие сайты проверяли, что я был тем, кто создал строку, я имею два варианта.

  1. Сервер возвращает меня назад, чтобы подтвердить (например, paypal, openid и т. Д.).
  2. Я использую общедоступные / частные ключи, чтобы доказать, что я отправил сообщение (например, PGP, DKIM и т. Д.).

Я не хочу настраивать HMAC, потому что это означает, что я должен использовать пользовательские ключи для каждого сайта, что было бы больно.

Из этих двух вариантов кажется, что # 2 будет экономить на полосе пропускания, что делает его лучшим выбором.

Итак, как вы можете настроить криптографию открытого / закрытого ключа с помощью PHP и есть ли какие-либо недостатки?

Solutions Collecting From Web of "Как шифровать данные в php с помощью общедоступных / закрытых ключей?"

Я бы создал S / MIME public / private keypairs с помощью OpenSSL, а затем с помощью команды OpenSSL выполнил шифрование и дешифрование. Я считаю, что это превосходит использование PGP, потому что openssl включен в большинство Linux-операционных систем, а PGP – нет. OpenSSL также основан на стандартах и, как правило, легче работать, когда у вас есть команды вниз.

Я рекомендовал против «чистого-PHP» решения (чистым-PHP я имею в виду делать криптографию в PHP, вместо того, чтобы использовать PHP для вызова существующей библиотеки или отдельного исполняемого файла). Вы не хотите делать массовые криптографии в PHP. Слишком медленно. И вы хотите использовать OpenSSL, потому что это высокая производительность, и безопасность хорошо понятна.

Вот волшебство.

Чтобы сделать ключ X.509:

$subj="/C=US/ST=California/L=Remote/O=Country Govt./OU=My Dept/CN=Mr. Agent/emailAddress=agent@investiations.com" openssl req -x509 -newkey rsa:1024 -keyout mycert.key -out mycert.pem -nodes -subj $subj 

Это ставит закрытый ключ в mycert.key и открытый ключ в mycert.pem. Закрытый ключ не защищен паролем.

Теперь, чтобы подписать сообщение с S / MIME:

 openssl smime -sign -signer mycert.pem -inkey mycert.key <input >output 

Чтобы зашифровать сообщение с помощью S / MIME:

 openssl smime -encrypt -recip yourcert.pem <input >output 

Чтобы расшифровать сообщение с помощью S / MIME:

 openssl smime -decrypt -inkey mycert.key -certfile mycert.pem <input >output 

У меня также есть некоторые демонстрации использования OpenSSL из привязок языка C, но не от PHP.

Создание пары частных и открытых ключей с использованием функций PHP Openssl:

 // Configuration settings for the key $config = array( "digest_alg" => "sha512", "private_key_bits" => 4096, "private_key_type" => OPENSSL_KEYTYPE_RSA, ); // Create the private and public key $res = openssl_pkey_new($config); // Extract the private key into $private_key openssl_pkey_export($res, $private_key); // Extract the public key into $public_key $public_key = openssl_pkey_get_details($res); $public_key = $public_key["key"]; 

Затем вы можете зашифровать и дешифровать с помощью закрытых и открытых ключей:

 // Something to encrypt $text = 'This is the text to encrypt'; echo "This is the original text: $text\n\n"; // Encrypt using the public key openssl_public_encrypt($text, $encrypted, $public_key); $encrypted_hex = bin2hex($encrypted); echo "This is the encrypted text: $encrypted_hex\n\n"; // Decrypt the data using the private key openssl_private_decrypt($encrypted, $decrypted, $private_key); echo "This is the decrypted text: $decrypted\n\n"; 

PGP – хороший вариант – он реализован правильно и полностью (т.е. у вас мало места для ошибок безопасности с PGP). Я думаю, что этот SO-вопрос поможет вам взаимодействовать с GnuPG. Вопрос в том, будут ли и на других сайтах проверять вашу подпись. Вам необходимо либо соответствовать их требованиям механизма проверки, либо предоставить свой собственный модуль, который эти сайты будут использовать для проверки.

Также возможно, что вы можете использовать OAuth или OpenID для идентификации пользователей на этих других сайтах, но я не являюсь экспертом в этих технологиях.

Правило 1: Не выполняйте его самостоятельно, используйте библиотеку.

Какая библиотека? Вот мои рекомендуемые библиотеки криптографии с открытым ключом PHP :

  1. Halite , зависит от libsodium (но подчеркивает простоту и простоту использования в дополнение к безопасности).
  2. libsodium , из PECL
  3. EasyRSA , которая реализует безопасное шифрование с открытым ключом и подписи с открытым ключом, используя RSA в наиболее безопасных режимах (НЕ PKCS1v1.5, когда-либо!)
  4. phpseclib , от которого EasyRSA контактирует.

В общем, вам понадобится libsodium, если ваша цель – безопасность. Независимо от того, используете ли вы Halite, это вопрос вкуса.

Я написал пример шифрования и дешифрования с помощью openSSL в PHP и Python

http://glynrob.com/php/hashing-and-public-key-encryption/

Доступен исходный код Github.

Не забывайте, что для того, чтобы это работало, для доступа к секретному ключу должен быть доступен секретный ключ.