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로 실패했습니다.OpenSSL 오류 메시지: 오류: 14090086: SSL 루틴:SSL3_GET_SERVER_CERTIFICATE: 2행의 ...php에서 증명서 검증에 실패했습니다.
- 경고: file_get_contents(): 2행에서 암호화를 활성화하지 못했습니다.
- 경고: 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의 ...에서 작업이 실패했습니다.
Gentoo 서버를 사용하고 있습니다.최근에 PHP 버전 5.6으로 업그레이드했습니다.이 문제가 발생한 것은 업그레이드 후입니다.
REST 서비스를 다음과 같은 주소로 대체했을 때 발견했습니다.https://www.google.com
; 내 페이지는 잘 작동한다.
이전의 시도에서 나는 다음과 같이 설정했다.“verify_peer”=>false
file_get_peer=>false ignoring verify_peer=>false 라고 기재되어 있듯이, 그것을 인수로서 file_get_files 에 전달했습니다.하지만 작가가 지적한 것처럼, 그것은 아무런 차이가 없었다.
php.ini 파일에 다음 행이 있는지 서버 관리자에게 문의했습니다.
- extension=sysl.sysl.syslog
- allow_url_fopen = 온
Gentoo에 있기 때문에 openssl은 빌드 시 컴파일되며 php.ini 파일에는 설정되어 있지 않다고 합니다.
저도 확인했습니다allow_url_fopen
동작하고 있습니다.이 문제의 특수성 때문에도움이 될 만한 정보를 많이 찾지 못하고 있어요.혹시 이런 거 본 적 있어요?감사해요.
이 링크는 다음 항목에 매우 도움이 되었습니다.
http://php.net/manual/en/migration56.openssl.php
PHP 5.6에서 ssl을 열기 위해 수행된 변경을 설명하는 공식 문서 여기서 false로 설정해야 할 파라미터가 하나 더 발견되었습니다: "false_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= [
'ssl' => [
'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)
);
접속하려는 사이트의 루트 증명서가 컬번들에 포함되어 있는 것이 바람직합니다.그렇지 않은 경우에도 사이트의 루트 인증서를 가져와 인증서 파일에 넣을 때까지 작동하지 않습니다.
OpenSSL이 컴퓨터에 설치되어 있는지 확인한 후 이를 php.ini에 추가함으로써 이 문제를 해결했습니다.
openssl.cafile=/usr/local/etc/openssl/cert.pem
다음과 같이 컬을 사용하는 커스텀 함수를 작성하면 이 문제를 회피할 수 있습니다.
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;
}
그럼 그냥 사용하세요file_get_contents_curl
대신file_get_contents
https로 시작하는 URL을 호출할 때마다 사용합니다.
저는 PHP 5.6을 사용하고 있습니다.openssl 확장이 활성화 되어 있어야 합니다.구글 맵 api verify_peer를 호출하는 동안 false Below 코드가 작동하고 있습니다.
<?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를 php5.6으로 업데이트한 후 나에게 맞는 솔루션을 찾았습니다.
디폴트에서는, 다음과 같이 증명서를 배치하기 위한 올바른 디렉토리를 취득합니다.
php -r "print_r(openssl_get_cert_locations()['default_cert_file']);"
그런 다음 이를 사용하여 증명서를 취득하고 위의 코드에서 찾은 기본 위치에 저장합니다.
wget http://curl.haxx.se/ca/cacert.pem -O <default location>
기본적으로 환경변수 SSL_CERT_FILE을 다음 링크에서 다운로드한SSL 증명서의 PEM 파일 경로로 설정해야 합니다.http://curl.haxx.se/ca/cacert.pem
이걸 알아내는데 시간이 많이 걸렸어요
PHP 버전이 5인 경우 단말기에 다음 명령을 입력하여 cURL을 설치해 보십시오.
sudo apt-get install php5-curl
다음 절차에 따라 이 문제가 해결됩니다.
- 다음 링크에서 CA 증명서를 다운로드합니다.https://curl.haxx.se/ca/cacert.pem
- php.ini를 찾아 엽니다.
- 찾다
curl.cainfo
증명서를 다운로드한 위치에 절대 경로를 붙여넣습니다.curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
- WAMP/XAMPP(apache 서버)를 재기동합니다.
- 됐다!
그게 도움이 됐으면 좋겠어!!
처음에 활성화해야 합니다.curl
PHP의 확장자세한 것은, PHP 입니다.그런 다음 다음 기능을 사용할 수 있습니다.
function file_get_contents_ssl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3000); // 3 sec.
curl_setopt($ch, CURLOPT_TIMEOUT, 10000); // 10 sec.
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
file_get_contents(..) 함수와 같이 동작합니다.
예:
echo file_get_contents_ssl("https://www.example.com/");
출력:
<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
같은 문제에 부딪혔는데 아무 것도 작동하지 않았기 때문에 추가하려고 합니다(예를 들어 cacert.pem 파일 다운로드, php.ini의 cafile 설정 등).
NGINX 를 사용하고 있고 SSL 증명서에 「증명서」가 부속되어 있는 경우는, 중간 증명서 파일을 메인 「mydomain.com.crt」파일과 조합해 사용할 필요가 있습니다.Apache는 중간 인증서 전용 설정이 있지만 NGINX는 그렇지 않으므로 일반 인증서와 동일한 파일 내에 있어야 합니다.
이 오류가 발생하는 이유는 PHP에 신뢰할 수 있는 인증 기관 목록이 없기 때문입니다.
PHP 5.6 이후에는 시스템에서 신뢰하는 CA를 자동으로 로드합니다.그것으로 문제를 해결할 수 있습니다.상세한 것에 대하여는, http://php.net/manual/en/migration56.openssl.php 를 참조해 주세요.
각 요청 컨텍스트에서 CA 번들을 수동으로 지정해야 하기 때문에 PHP 5.5 이전 버전은 올바르게 설정하기가 매우 어렵습니다. 코드 주위에 뿌리고 싶지 않습니다.그래서 PHP 버전이 5.6보다 작을 경우 SSL 검증이 무효가 되는 것을 코드로 결정했습니다.
$req = new HTTP_Request2($url);
if (version_compare(PHP_VERSION, '5.6.0', '<')) {
//correct ssl validation on php 5.5 is a pain, so disable
$req->setConfig('ssl_verify_host', false);
$req->setConfig('ssl_verify_peer', false);
}
XAMPP 및 OSX의 PHP 7에서도 동일한 오류가 발생하였습니다.
위의 답변은 https://stackoverflow.com/에 기재되어 있습니다만, 저는 문제가 완전히 해결되지 않았습니다.file_get_contents()를 다시 작동시키기 위해 완전한 증명서 체인을 제공해야 했습니다.그렇게 했어요.
루트/중간 증명서 취득
우선 루트 증명서와 중간 증명서가 무엇인지 알아내야 했다.
가장 편리한 방법은 아마도 ssl shopper와 같은 온라인 인증 도구일 것입니다.
거기서 3개의 증명서, 1개의 서버 증명서, 2개의 체인 증명서(하나는 루트, 다른 하나는 중간 증명서)를 발견했습니다.
둘 다 인터넷에서 검색만 하면 돼요.내 경우, 루트는 다음과 같습니다.
thawte DV SSL SHA256 CA
그리고 그의 URL thawte.com로 연결됩니다.그래서 저는 이 증명서를 텍스트 파일에 넣고 중간자에게도 똑같이 했습니다.다 했어요.
호스트 증명서를 취득하다
다음으로 서버 인증서를 다운로드해야 했습니다.Linux 또는 OS X에서는 openssl을 사용하여 실행할 수 있습니다.
openssl s_client -showcerts -connect whatsyoururl.de:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /tmp/whatsyoururl.de.cert
이제 그들을 모두 불러모으시오
이제 모든 파일을 하나의 파일로 병합합니다.(하나의 폴더에 넣는 것이 좋을지도 모릅니다.그냥 하나의 파일로 통합했습니다).다음과 같이 할 수 있습니다.
cat /tmp/thawteRoot.crt > /tmp/chain.crt
cat /tmp/thawteIntermediate.crt >> /tmp/chain.crt
cat /tmp/tmp/whatsyoururl.de.cert >> /tmp/chain.crt
체인을 찾을 수 있는 위치를 PHP에 알립니다.
편리한 함수 openssl_get_cert_locations()가 있습니다.이 함수는 PHP가 증명서 파일을 찾고 있는 장소를 알려줍니다.또한 이 파라미터는 증명서 파일의 위치를 file_get_contents()에 지시합니다.어쩌면 둘 다 효과가 있을지도 몰라.파라메타 방식을 선호합니다.(상기 솔루션보다)
이게 제 PHP 코드입니다.
$arrContextOptions=array(
"ssl"=>array(
"cafile" => "/Applications/XAMPP/xamppfiles/share/openssl/certs/chain.pem",
"verify_peer"=> true,
"verify_peer_name"=> true,
),
);
$response = file_get_contents($myHttpsURL, 0, stream_context_create($arrContextOptions));
이상입니다. file_get_contents()가 다시 작동합니다.CURL도 없고 보안 결함도 없기를 바랍니다.
"https://localhost/..." 파일을 열려고 하는 자기서명증명서를 가진 개발자 머신에서도 동일한 ssl 문제가 발생하였습니다(ph 7, Windows에서는 xampp).root-certificate-assembly(cacert.pem)는 정상적으로 동작하지 않았습니다.다운로드 받은 cacert.pem의 apache server.crt-File에서 코드를 수동으로 복사하고 php.ini의 openssl.crt-pem 엔트리를 실행했습니다.
또 하나 시도해 볼 수 있는 것은 재설치입니다.ca-certificates
여기에 자세히 나와 있습니다.
# yum reinstall ca-certificates
...
# update-ca-trust force-enable
# update-ca-trust extract
또, 여기서 설명하는 대로, 문제의 1 사이트의 증명서를 명시적으로 허가하는 것도 필요합니다(특히, 1 사이트가 자신의 서버이며, 이미 .pem이 액세스 가능한 경우).
# cp /your/site.pem /etc/pki/ca-trust/source/anchors/
# update-ca-trust extract
Cent에서 PHP 5.6으로 업그레이드한 후 이 SO 오류가 발생했습니다.OS 6은 갱신할 필요가 있는 값싼SSL 보안 증명서를 가진 서버 자체에 액세스하려고 했습니다만, 그 대신 letsencrypt 증명서를 설치하고 위의 두 가지 절차를 통해 문제가 해결되었습니다.나는 왜 두 번째 단계가 필요했는지 모르겠다.
유용한 명령어
openssl 버전 보기:
# openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
PHP cli ssl 현재 설정 보기:
# php -i | grep ssl
openssl
Openssl default config => /etc/pki/tls/openssl.cnf
openssl.cafile => no value => no value
openssl.capath => no value => no value
<?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 7.2만 테스트하면 정상적으로 동작합니다.
에러에 대해서
[2017년 5월 11일 19:19:13 미국/시카고] PHP 경고: file_get_contents(): 코드 1로 SSL 작업이 실패했습니다.OpenSSL 오류 메시지: 오류: 14090086:SSL 루틴:ssl3_get_server_certificate:증명서 검증 실패
openssl에서 참조하는 증명서와 디렉토리의 권한을 확인했습니까?
당신은 이걸 할 수 있다.
var_dump(openssl_get_cert_locations());
이것과 비슷한 것을 얻기 위해
array(8) {
["default_cert_file"]=>
string(21) "/usr/lib/ssl/cert.pem"
["default_cert_file_env"]=>
string(13) "SSL_CERT_FILE"
["default_cert_dir"]=>
string(18) "/usr/lib/ssl/certs"
["default_cert_dir_env"]=>
string(12) "SSL_CERT_DIR"
["default_private_dir"]=>
string(20) "/usr/lib/ssl/private"
["default_default_cert_area"]=>
string(12) "/usr/lib/ssl"
["ini_cafile"]=>
string(0) ""
["ini_capath"]=>
string(0) ""
}
이 문제는 한동안 당황스러웠지만 내 "certs" 폴더에 755개의 권한이 있어야 하는 700개의 권한이 있다는 것을 알게 되었습니다.이 폴더는 키의 폴더가 아니라 증명서의 폴더입니다.SSL 권한에 대해 이 링크를 읽을 것을 권장합니다.
한번 해봤는데
chmod 755 certs
적어도 나에게는 문제는 해결되었다.
12.4/Mamp 6.6/Homebrew 3.5.2/Opensl@3 수정
터미널
버전 확인
openssl version -a
제 의견은 다음과 같습니다.
...
OPENSSLDIR: "/opt/homebrew/etc/openssl@3"
...
그래서 나는 홈브루의 디르를 뒤졌다./opt/homebrew/etc/openssl@3
cert.pem을 찾아 mamp의 현재 버전의 php.ini 파일이 homebrew의 올바른 openssl 버전의 cert.pem을 가리키고 있는지 확인합니다.
php.ini에 추가
openssl.cafile=/opt/homebrew/etc/openssl@3/cert.pem
사용할 때 다른 보안 페이지에 대해 동일한 문제가 발생했습니다.wget
또는file_get_contents
많은 조사(이 질문에 대한 응답도 포함)를 통해 Curl과 PHP-Curl을 설치하는 간단한 해결책이 도출되었습니다.제가 제대로 이해했다면 Curl은 문제를 해결한 Comodo용 루트 CA를 가지고 있습니다.
Curl 및 PHP-Curl 애드온을 설치한 후 Apache를 다시 시작합니다.
sudo apt-get install curl
sudo apt-get install php-curl
sudo /etc/init.d/apache2 reload
이제 모두 작동한다.
저는 Windows 10 머신(localhost)에서 XAMPP를 실행하고 있었는데 최근 PHP 8로 업그레이드했습니다.file_get_contents()를 통해 로컬호스트 HTTPS 링크를 열려고 했습니다.
제 php.ini 파일에 다음과 같은 행이 있었습니다.
openssl.cafile="C:\Users\[USER]\xampp\apache\bin\curl-ca-bundle.crt"
이것은 "외부" URL을 검증하기 위해 사용되는 증명서 번들로, 일부 사람들이 논의한 것처럼 Mozilla의 패키지입니다.XAMPP가 그렇게 온 것인지, 아니면 내가 과거에 설정한 것인지 모르겠다.
어느 시점에서 로컬호스트에 HTTPS를 설정했기 때문에 다른 증명서 번들이 생성되었습니다.이 번들을 사용하여 "localhost" URL을 검증해야 합니다.번들이 어디에 있는지 기억하기 위해 httpd-ssl.conf를 열었더니 다음과 같은 행이 있었습니다.
SSLCertificateFile "conf/ssl.crt/server.crt"
(완전한 경로는 C:였습니다).\Users[USER]\xampp\apache\conf\ssl.crt\server.crt)
localhost와 outside URL을 동시에 동작시키기 위해 localhost "server.crt" 파일의 내용을 Mozilla 번들 "curl-ca-bundle.crt"에 복사했습니다.
.
.
.
m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
-----END CERTIFICATE-----
Localhost--I manually added this
================================
-----BEGIN CERTIFICATE-----
MIIDGDCCAgCgAwIBAgIQIH+mTLNOSKlD8KMZwr5P3TANBgkqhkiG9w0BAQsFADAU
...
이 시점에서 추가 설정 없이 localhost URL과 outside URL 모두에서 file_get_contents()를 사용할 수 있습니다.
file_get_contents("https://localhost/...");
file_get_contents("https://google.com");
$csm = stream_false_create(['ssl' => ['sl_files_get_contents' ]), $sourceCountry=file_get_contents('https://api.wipmania.com/'.$ip.'?website.com', FALSE, $csm);
언급URL : https://stackoverflow.com/questions/26148701/file-get-contents-ssl-operation-failed-with-code-1-failed-to-enable-crypto
'programing' 카테고리의 다른 글
JavaScript에서 현재 연도 가져오기 (0) | 2022.10.13 |
---|---|
PHP에서 유용한 오류 메시지를 얻으려면 어떻게 해야 합니까? (0) | 2022.10.13 |
Google Colab: Google 드라이브에서 데이터를 읽는 방법 (0) | 2022.10.13 |
MySQL에서 선택한 값의 쉼표로 구분된 문자열 (0) | 2022.10.13 |
열려 있는 MySQL 연결 수를 확인하려면 어떻게 해야 합니까? (0) | 2022.10.13 |