bars80081
Новичок
Добрый день,
у меня возникла проблема, видимо, связанная исключительно с моей внимательностью.
проблема: отправляю зашифрованное и подписанное сообщение на удалённый сервер, он отвечает "ключ неверен".
пишу сюда только потому, что не знаю что делать. вдруг допустил какую-то невероятно глупую ошибку при пользовании библиотекой openssl, а вы её сразу увидите
задача:
текст шифруется открытым ключом шлюза и, подписав SHA1-дайджест зашифрованного сообщения при помощи своего закрытого ключа, отправляется на шлюз
сервер работоспособен и отлажен, ибо другие с ними работают без проблем
сокетное соединение также налажено и проверено при помощи нешифрованных запросов
ключи сгенерированы непосредственно на той же машине, с которой происходит отсылка запросов.
генерация ключей происходила этим кодом (который я благополучно скопипастил без размышления над его сущностью):
у меня небольшие опасения по поводу функции openssl_x509_export(). не может ли она быть специфичной функцией для определённого типа шифрования. у меня в условиях были только RSA, паддинг PKCS1 и SHA1.
шифрование и отсылка сообщений происходит следующим кодом:
сервер полностью воспринимает, что ему приходит. он читает заголовок, узнаёт из него (выставлен флаг), что сообщение зашифровано. возвращает ошибку: "неверный ключ", то есть не получается расшифровать.
в общем, надеюсь в этой теме только на то, что ваш натренированный глаз вдруг вычленит несуразную ересь в моём коде.
у меня возникла проблема, видимо, связанная исключительно с моей внимательностью.
проблема: отправляю зашифрованное и подписанное сообщение на удалённый сервер, он отвечает "ключ неверен".
пишу сюда только потому, что не знаю что делать. вдруг допустил какую-то невероятно глупую ошибку при пользовании библиотекой openssl, а вы её сразу увидите
задача:
текст шифруется открытым ключом шлюза и, подписав SHA1-дайджест зашифрованного сообщения при помощи своего закрытого ключа, отправляется на шлюз
сервер работоспособен и отлажен, ибо другие с ними работают без проблем
сокетное соединение также налажено и проверено при помощи нешифрованных запросов
ключи сгенерированы непосредственно на той же машине, с которой происходит отсылка запросов.
генерация ключей происходила этим кодом (который я благополучно скопипастил без размышления над его сущностью):
PHP:
static function generateKeys($bits_count = 1024) {
//generate public key
$params = array(
'digest_alg' => 'sha1',
'private_key_bits' => $bits_count,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'encrypt_key' => false
);
$private_key = openssl_pkey_new($params);
openssl_pkey_export($private_key, $private_key_string);
//generate certificate (to get a public key from it)
$csr = openssl_csr_new(array(), $private_keys);
$cert = openssl_csr_sign($csr, null, $private_key, 1);
openssl_x509_export($cert, $str_cert);
//get the public key from the certificate
$public_key = openssl_pkey_get_public($str_cert);
//get the PEM-encoded public key
$public_key_details = openssl_pkey_get_details($public_key);
$public_key_string = $public_key_details['key'];
return array('private' => $private_key_string, 'public' => $public_key_string);
}
шифрование и отсылка сообщений происходит следующим кодом:
PHP:
$key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANfSTfT8TX9ik
... ещё 2 строчки ...
KDVXfcZAo2fmazFv+QIDAQAB
-----END PUBLIC KEY-----';
$sirena->public_key = $key;
$key = '-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANfSTfT8+bfSTtF3
... ещё 12 строчек ...
luTHbgAuBgeJGpA=
-----END PRIVATE KEY-----';
$sirena->private_key = $key;
$key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANfSTfT8VOiDOP
... ещё 2 строчки ...
Ya9y4c56YQhoWGo6hwIDAQAB
-----END PUBLIC KEY-----';
$sirena->server_public_key = $key;
$message = '12341234';
$sirena->set_crypted_open_message($message);
$q = $sirena->send();
class sirena {
public $public_key = '';
public $private_key = '';
public $server_public_key = '';
private $message = '';
private $header = '';
private function public_encrypt($data, $public_key = '') {
$result = openssl_public_encrypt($data, $crypted, $public_key, OPENSSL_PKCS1_PADDING);
return $crypted;
}
private function sign($data, $private_key = '') {
$key_id = openssl_pkey_get_private($private_key);
$result = openssl_sign($data, $signature, $key_id, OPENSSL_ALGO_SHA1);
openssl_free_key($key_id);
return $signature;
}
public function set_crypted_open_message($s = '') {
$message_encrypt = $this->public_encrypt($s, $this->server_public_key);
$message_len = strlen($message_encrypt);
$subscribe = $this->sign($s, $this->private_key);
// формат сообщения: 4 байта на длину тела + тело сообщения + подпись
$res = pack('N', $message_len);
$res .= $message_encrypt;
$res .= $subscribe;
$this->message = $res;
}
public function send() {
$this->set_header(); // возвращает 100-байтовый заголовок, отлаженный, как и сокетное соединение. сервер его понимает
$query = $this->header . $this->message;
$q = $this->socketer->write($query);
return $q;
}
}
в общем, надеюсь в этой теме только на то, что ваш натренированный глаз вдруг вычленит несуразную ересь в моём коде.