Cómo utilizar Socket para obtener el certificado SSL y la clave pública del sitio web
Código de muestra:
//Crear contexto de transmisión
$context = stream_context_create([
'ssl' => [ p>
'capture_peer_cert' => verdadero,
'capture_peer_cert_chain' => verdadero,
],
]);
$recurso = stream_socket_client("ssl://$dominio:$puerto", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
$cert = stream_context_get_params($recurso);
$ssl = $cert['options']['ssl'];
$resource = $ssl['peer_certificate'];
// Sitio web Solo existe la clave pública en el certificado, que se puede exportar a través de openssl_pkey_get_details
$ret = [
'crt' => '',
' pub' => ' ',
];
$pkey = openssl_pkey_get_public($recurso);
$ret['pub'] = openssl_pkey_get_details($ pkey)['key '];
openssl_x509_export($resource, $pem);
$ret['crt'] = $pem;
foreach ($ssl[' peer_certificate_chain'] como $recurso)
{
openssl_x509_export($recurso, $pem);
$ret['crt'] .= "\n " . $pem;
}
// Guardar $ret['crt'] como dominio.crt
// Guardar $ ret['pub' ] Para dominio.pub
return $ret;
Verifique si la clave pública A en el certificado es correcta, exporte la clave pública B a través de la clave privada, y compare los dos para encontrar que son consistentes.
$dominio = 'blog.zhengxianjun.com';
$puerto = '443';
// ...
$pub_a = $ret['pub'];
$private_key_path = '/conf/ssl/blog.zhengxianjun.com.key';
//El certificado no tiene una contraseña establecida, $passphrase es una cadena vacía
$pkey = openssl_pkey_get_private(file_get_content($private_key_path), $passphrase = '');
$pub_b = openssl_pkey_get_details($pkey )['key '];
// Ambos son consistentes
var_dump($pub_a === $pub_b);
Otro uso de la función stream_socket_client es conocer la IP del servidor, se puede obtener el nombre de dominio que el servidor podrá utilizar.
$resource = stream_socket_client("ssl://$ip:$port", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
$cert = stream_context_get_params( $resource);
//Analizar el certificado de formato X.509
$info = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
// Obtener la lista de nombres de dominio confiables en el certificado
$domain = str_replace('DNS:', '', $info['extensions']['subjectAltName' ]) ;
Como puedes ver arriba, obtener el certificado del sitio web no permite obtener la clave privada.
En algunos sitios que usan CDN, si usa HTTPS y desea usar su propio nombre de dominio, ¿debe proporcionar su clave privada al proveedor de CDN? De hecho, no es necesario que la ruta del certificado y el nombre de usuario (nombre de dominio que admite https) sean coherentes.
Es decir, cuando utiliza su propio nombre de dominio para la aceleración CDN, no necesita usar su propio certificado SSL. Solo necesita agregar su propio nombre de dominio CDN a la lista de nombres de dominio del certificado del fabricante. .