> 백엔드 개발 > PHP 문제 > PHP에서 https 양방향 인증을 구현하는 방법

PHP에서 https 양방향 인증을 구현하는 방법

藏色散人
풀어 주다: 2023-03-04 08:46:01
원래의
4597명이 탐색했습니다.

PHP에서 https를 구현하는 방법: 먼저 openssl 구성을 수정한 다음 CA 루트 인증서를 생성하고 인증서 비밀번호를 6자 이상으로 설정한 다음 마지막으로 nginx를 구성합니다. PHP 컬 테스트를 수행합니다.

PHP에서 https 양방향 인증을 구현하는 방법

권장: "PHP Video Tutorial"

php는 https(tls/ssl) 양방향 인증을 구현합니다

일반적으로 https 배포 시 SSL 단방향 인증을 기반으로 하며, 즉, 클라이언트가 서버를 인증하는 한 서버는 클라이언트를 인증할 필요가 없습니다.

그러나 은행, 금융 및 기타 분야와 같이 보안이 더 높은 일부 시나리오에서는 일반적으로 클라이언트 인증이 필요합니다. 이를 통해 SSL의 양방향 인증이 가능해집니다.

nginx의 ssl_client_certificate 매개변수는 하나의 클라이언트 공개 키만 지정할 수 있으므로 통신을 위해 클라이언트를 추가하는 경우 새 서버를 구성해야 합니다.

n:1 모드는 CA의 계단식 인증서 모드를 통해 구현됩니다. 먼저 CA 루트 수준 인증서 세트를 직접 생성한 다음 이를 사용하여 클라이언트 인증서로 보조 인증서를 생성합니다.

이때, 클라이언트 개인키 서명은 해당 클라이언트 공개키뿐만 아니라 루트 인증서의 공개키로도 확인할 수 있습니다.

이 내용을 보고 깨달으셔야 합니다. 다음은 작동 방법에 대한 간략한 소개입니다.

1 준비

1.1 Openssl 디렉터리 준비

일반적으로 openssl의 구성 파일은 /etc/pki/tls 디렉터리에 있습니다. so:

mkdir /etc/pki/ca_linvo
cd /etc/pki/ca_linvo
mkdir root server client newcerts
echo 01 > serial
echo 01 > crlnumber
touch index.txt
로그인 후 복사

1.2 openssl 구성 준비

openssl 구성 수정

vi /etc/pki/tls/openssl.cnf

이 문장을 주석 처리하고 다음 문장으로 바꾸세요

#default_ca      = CA_default
default_ca      = CA_linvo
로그인 후 복사

[CA_default의 전체 부분을 복사하세요. ] 복사본 한 개, 위의 이름으로 변경합니다. [CA_linvo]

내부에서 다음 매개변수를 수정합니다.

dir = /etc/pki/ca_linvo
certificate = $dir/root/ca.crt
private_key = $dir/root/ca.key
로그인 후 복사

저장 및 종료

2 CA 루트 수준 인증서 생성

生成key:openssl genrsa -out /etc/pki/ca_linvo/root/ca.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.csr
生成crt:openssl x509 -req -days 3650 -in /etc/pki/ca_linvo/root/ca.csr -signkey /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.crt
生成crl:openssl ca -gencrl -out /etc/pki/ca_linvo/root/ca.crl -crldays 7
로그인 후 복사

생성된 루트 수준 인증서 파일은 모두 /에 있습니다. etc/pki/ca_linvo/ 루트/ 디렉터리 아래

참고: 인증서를 생성할 때 인증서 비밀번호 길이는 6자 이상인 것이 좋습니다. Java의 keytool 도구에 이에 대한 요구 사항이 있는 것 같기 때문입니다.

3 서버 인증서 만들기

生成key:openssl genrsa -out /etc/pki/ca_linvo/server/server.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/server/server.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/server/server.crt -days 3650
로그인 후 복사

지침:

1. 여기서 생성된 crt는 현재 CA 루트 인증서 아래의 캐스케이드 인증서입니다. 실제로 서버 인증서는 주로 일반 단방향 https를 구성하는 데 사용됩니다. 계단식 모드는 사용되지 않습니다.

openssl rsa -in /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.key
openssl x509 -req -in /etc/pki/ca_linvo/server/server.csr -signkey /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.crt -days 3650
로그인 후 복사

2 -days 매개변수는 필요에 따라 인증서의 유효 기간을 설정할 수 있습니다. 예를 들어 기본값은 365일입니다.

生成key:openssl genrsa -des3 -out /etc/pki/ca_linvo/client/client.key 1024
生成csr:openssl req -new -key /etc/pki/ca_linvo/client/client.key -out /etc/pki/ca_linvo/client/client.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/client/client.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/client/client.crt -days 3650
로그인 후 복사

지침:

1. 여기에서는 계단식 인증서를 사용해야 하며 이를 반복할 수 있습니다. 여러 클라이언트 인증서 세트를 생성하는 단계

2 crt를 생성할 때 다음 오류가 발생할 수 있습니다.

openssl TXT_DB error number 2 failed to update database
로그인 후 복사

여기를 참조하세요. 작업.

첫 번째 방법, 즉 nginx를 구성하기 위해 index.txt.attr의 Unique_subject = no

5를 사용하고 있습니다

여기에는 서버 세그먼트의 주요 부분만 나열되어 있습니다.

ssl_certificate  /etc/pki/ca_linvo/server/server.crt;#server公钥
ssl_certificate_key  /etc/pki/ca_linvo/server/server.key;#server私钥
ssl_client_certificate   /etc/pki/ca_linvo/root/ca.crt;#根级证书公钥,用于验证各个二级client
ssl_verify_client on;
로그인 후 복사

Restart Nginx

6 테스트

6.1 브라우저 테스트

양방향 인증으로 인해 브라우저를 통해 직접 https 주소에 접속하면 400 Bad Request(필요한 SSL 인증서가 전송되지 않음) 메시지가 표시되며, 클라이언트 인증서를 설치해야 합니다. 로컬 머신.

Windows에 설치된 인증서에는 p12 형식이라고도 하는 pfx 형식이 필요합니다. 생성 방법은 다음과 같습니다.

openssl pkcs12 -export -inkey /etc/pki/ca_linvo/client/client.key -in /etc/pki/ca_linvo/client/client.crt -out /etc/pki/ca_linvo/client/client.pfx
로그인 후 복사

그런 다음 Windows로 이동하여 두 번 클릭하여 설치하면 설정한 비밀번호를 입력하라는 메시지가 표시됩니다. 인증서를 생성합니다.

설치가 성공적으로 완료되면 브라우저를 다시 시작하고 액세스할 URL을 입력하세요. 브라우저에서 방금 설치한 인증서를 선택하라는 메시지를 표시할 수 있습니다.

이때 일부 브라우저에서는 인증서를 신뢰할 수 없거나 주소가 안전하지 않다는 등의 메시지를 사용자에게 표시합니다. 이는 우리 서버 인증서가 실제 권위 있는 CA 기관이 아닌 자체적으로 발급한 것이기 때문입니다(보통 매우 비쌉니다~) , 그냥 무시하세요.

6.2 php 컬 테스트

설정해야 할 주요 컬 매개변수는 다음과 같습니다:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书,不是CA机构颁布的也没关系  
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名,如果不想验证也可设为0  
curl_setopt($ch, CURLOPT_VERBOSE, '1'); //debug模式,方便出错调试  
curl_setopt($ch, CURLOPT_SSLCERT, CLIENT_CRT); //client.crt文件路径,这里我用常量代替  
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, CRT_PWD); //client证书密码  
curl_setopt($ch, CURLOPT_SSLKEY, CLIENT_KEY); //client.key文件路径  
 
CURLOPT_TIMEOUT:超时时间
CURLOPT_RETURNTRANSFER:是否要求返回数据
CURLOPT_SSL_VERIFYPEER:是否检测服务器的证书是否由正规浏览器认证过的授权CA颁发的
CURLOPT_SSL_VERIFYHOST:是否检测服务器的域名与证书上的是否一致
CURLOPT_SSLCERTTYPE:证书类型,"PEM" (default), "DER", and"ENG".
CURLOPT_SSLCERT:证书存放路径
CURLOPT_SSLCERTPASSWD:证书密码,没有可以留空
CURLOPT_SSLKEYTYPE:私钥类型,"PEM" (default), "DER", and"ENG".
CURLOPT_SSLKEY:私钥存放路径
 
 
function curl_post_ssl($url, $vars, $second=30,$aHeader=array())
{
    $ch = curl_init();
    //curl_setopt($ch,CURLOPT_VERBOSE,'1');
    curl_setopt($ch,CURLOPT_TIMEOUT,$second);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLCERT,'/data/cert/php.pem');
    curl_setopt($ch,CURLOPT_SSLCERTPASSWD,'1234');
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLKEY,'/data/cert/php_private.pem');
 
    if( count($aHeader) >= 1 ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
    }
 
    curl_setopt($ch,CURLOPT_POST, 1);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
    $data = curl_exec($ch);
    curl_close($ch);
    if($data)
            return $data;
    else   
            return false;
}
로그인 후 복사

확인에 실패했습니다. nginx 오류 로그에는 다음 정보가 포함됩니다.

2017/06/05 17:45:07 [crit] 16084#0: *27458991 SSL_do_handshake() failed (SSL: error:04067084:rsa routines:RSA_EAY_PUBLIC_DECRYPT:data too large for modulus e
rror:1408807A:SSL routines:ssl3_get_cert_verify:bad rsa signature) while SSL handshaking, client: 116.255.208.194, server: 0.0.0.0:443
로그인 후 복사

6.3 php 비누 테스트

먼저 빌드해야 합니다. 클라이언트 pem 형식 인증서의 경우 openssl 명령을 사용할 수도 있지만 이미 crt와 키가 있으므로 수동 병합도 매우 간단합니다.

새 파일을 만들고 -----BEGIN CERTIFICATE---- 및 - crt에서 ----END CERTIFICATE-----(이 두 구분선 포함) 사이에 base64 콘텐츠를 복사한 다음 -----BEGIN RSA PRIVATE KEY----- 및 ----를 입력합니다. -END RSA PRIVATE KEY----- 사이의 내용을 복사하여 client.pem으로 저장합니다.

실제로 더 쉽다면 다음 명령을 사용하여 두 파일을 직접 병합할 수 있습니다.

cat /etc/pki/ca_linvo/client/client.crt /etc/pki/ca_linvo/client/client.key > /etc/pki/ca_linvo/client/client.pem
로그인 후 복사

pem 파일을 사용하면 PHP에 내장된 SoapClient를 사용하여 호출할 수 있습니다. 생성자는 두 번째 매개변수를 설정해야 합니다. :

$header = array(          
    'local_cert' => CLIENT_PEM, //client.pem文件路径  
    'passphrase' => CRT_PWD //client证书密码  
    );  
$client = new SoapClient(FILE_WSDL, $header); //FILE_WSDL为要访问的https地址
로그인 후 복사

이전 블로그 마지막으로 local_cert를 원격 경로로 설정하면 wsdl을 처음 얻을 때 클라이언트 인증서를 사용하지 않았기 때문에 오류가 발생한다고 합니다.

하지만 이번 테스트에서는 문제가 없었습니다. 로컬 파일로 저장할 필요는 없고, 원격으로 가져오면 됩니다.

원래 이전 인증서에 문제가 있는 줄 알았는데 이전 인증서를 계속 사용할 수 있다는게 참 이상하네요~~~~~

위 내용은 PHP에서 https 양방향 인증을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿