Как зашифровать данные в PHP, используя публичные / частные ключи?

StackOverflow https://stackoverflow.com/questions/4629537

Вопрос

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

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

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

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

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

Это было полезно?

Решение

Я бы создал S / MIME Public / Private Keypares, используя OpenSSL, а затем использовать команду OpenSSL для выполнения шифрования и дешифрования. Я считаю, что это превосходит PGP, потому что OpenSSL входит в комплект по большинству операционных систем Linux, а PGP не. OpenSSL также на основе стандартов и, как правило, проще работать, как только у вас есть команды.

Я рекомендовал к раствору «Pure-Php» (Pure-Php, я имею в виду выполнение крипто в PHP, а не использовать PHP, чтобы вызвать существующую библиотеку или отдельный исполняемый файл). Вы не хотите делать оптом Crypto в 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";

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

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

  1. Галита, зависит от libsodium (но подчеркивает простоту и простоту использования в дополнение к безопасности).
  2. Либесид, от PECL
  3. Эйрса, который реализует безопасную ключевое шифрование и подписи для открытых ключей с использованием RSA в самых безопасных режимах (не PKCS1V1.5, когда-либо!)
  4. phpseclib., какая Эйрса Ковчикам от.

В общем, вы хотите Libsodium, если безопасность - ваша цель. Независимо от того, используете ли вы галиты - это вопрос вкуса.

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

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

Я написал пример шифрования и расшифровки с OpenSSL в PHP и Python

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

Исходный код GitHub доступен.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top