[php] file_get_contents () : 코드 1로 SSL 작업 실패, 암호화 사용 실패

서버에서 만든 PHP 페이지에서이 특정 REST 서비스에 액세스하려고했습니다. 문제를이 두 줄로 좁혔습니다. 그래서 내 PHP 페이지는 다음과 같습니다

<?php
$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json");

echo $response; ?>

페이지가 2 행에서 다음 오류와 함께 종료됩니다.

  • 경고 : file_get_contents () : SSL 작업 코드 1 실패
    • 경고 : file_get_contents () : 2 행의 … php에서 암호화를 활성화하지 못했습니다.
    • 경고 : file_get_contents ( https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json) : 스트림을 열지 못했습니다 : 2 행의 … php에서 작업이 실패했습니다.

우리는 젠투 서버를 사용하고 있습니다. 최근에 PHP 버전 5.6으로 업그레이드했습니다. 이 문제가 나타 났을 때 업그레이드 이후였습니다.

REST 서비스를 다음과 같은 주소로 바꿀 때 찾았습니다 https://www.google.com. 내 페이지가 잘 작동합니다.

이전 시도에서 나는을 설정 “verify_peer”=>false하고 여기에 설명 된대로 file_get_contents에 인수로 전달했습니다. verify_peer => false? 그러나 작가가 지적한 것처럼; 아무런 차이가 없었습니다.

php.ini 파일에 다음 줄이 있는지 서버 관리자에게 물었습니다.

  • extension = php_openssl.dll
  • allow_url_fopen = 켜기

그는 Gentoo를 사용하고 있기 때문에 우리가 빌드 할 때 openssl이 컴파일된다고 말했습니다. php.ini 파일에 설정되어 있지 않습니다.

또한 allow_url_fopen작동하고 있음을 확인했습니다 . 이 문제의 특수한 특성으로 인해; 도움이 필요한 정보를 많이 찾지 못했습니다. 이런 사람이 있습니까? 감사.



답변

이것은 다음을 찾는 데 매우 유용한 링크였습니다.

http://php.net/manual/en/migration56.openssl.php

PHP 5.6에서 ssl을 여는 변경 사항을 설명하는 공식 문서 여기에서 내가 false로 설정해야하는 하나 이상의 매개 변수에 대해 배웠습니다. “verify_peer_name”=> false

참고 : 이것은 보안에 매우 중요한 영향을 미칩니다. 확인을 비활성화하면 MITM 공격자 가 잘못된 인증서를 사용하여 요청을 도청 할 수 있습니다. 로컬 개발에서이 작업을 수행하는 것이 유용 할 수 있지만 프로덕션에서는 다른 접근 방식을 사용해야합니다.

작업 코드는 다음과 같습니다.

<?php
$arrContextOptions=array(
    "ssl"=>array(
        "verify_peer"=>false,
        "verify_peer_name"=>false,
    ),
);

$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));

echo $response; ?>


답변

확인 만 끄면 안됩니다. 오히려 번들이 할 인증서 번들을 다운로드 해야합니까?

그런 다음 웹 서버에 저장하면 PHP를 실행하는 사용자에게 파일을 읽을 수있는 권한을 부여 할 수 있습니다. 그런 다음이 코드가 효과가 있습니다.

$arrContextOptions=array(
    "ssl"=>array(
        "cafile" => "/path/to/bundle/cacert.pem",
        "verify_peer"=> true,
        "verify_peer_name"=> true,
    ),
);

$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));

다행히도 액세스하려는 사이트의 루트 인증서가 curl 번들에 있습니다. 그렇지 않은 경우 사이트의 루트 인증서를 가져 와서 인증서 파일에 넣을 때까지 여전히 작동하지 않습니다.


답변

OpenSSL이 내 컴퓨터에 설치되어 있는지 확인한 다음 이것을 php.ini에 추가하여 문제를 해결했습니다.

openssl.cafile=/usr/local/etc/openssl/cert.pem


답변

다음과 같이 curl을 사용하는 사용자 정의 함수를 작성하여이 문제를 해결할 수 있습니다.

function file_get_contents_curl( $url ) {

  $ch = curl_init();

  curl_setopt( $ch, CURLOPT_AUTOREFERER, TRUE );
  curl_setopt( $ch, CURLOPT_HEADER, 0 );
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
  curl_setopt( $ch, CURLOPT_URL, $url );
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );

  $data = curl_exec( $ch );
  curl_close( $ch );

  return $data;

}

그런 다음 https로 시작하는 URL을 호출 할 때마다 file_get_contents_curl대신 사용 file_get_contents하십시오.


답변

나를 위해 PHP 5.6을 사용하고 있습니다. openssl 확장 기능을 활성화하고 Google지도를 호출하는 동안 api verify_peer make false 아래 코드가 작동합니다.

<?php
$arrContextOptions=array(
    "ssl"=>array(
         "verify_peer"=>false,
         "verify_peer_name"=>false,
    ),
);
$url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="
      . $latitude
      . ","
      . $longitude
      . "&sensor=false&key="
      . Yii::$app->params['GOOGLE_API_KEY'];

$data = file_get_contents($url, false, stream_context_create($arrContextOptions));

echo $data;
?>


답변

PHP 버전이 5 인 경우 터미널에 다음 명령을 입력하여 cURL을 설치하십시오.

sudo apt-get install php5-curl


답변

기본적으로 환경 변수 SSL_CERT_FILE을 http://curl.haxx.se/ca/cacert.pem 링크에서 다운로드 한 ssl-certificate의 PEM 파일 경로로 설정해야합니다 .

이것을 알아내는 데 많은 시간이 걸렸습니다.