How to implement https two-way authentication in php
How to implement https in php: first modify the openssl configuration; then create the CA root certificate and set the certificate password to be greater than or equal to 6 characters; then create the server certificate and client certificate; finally configure nginx and perform php Just curl the test.
Recommended: "PHP Video Tutorial"
php implements https (tls/ssl) two-way authentication
Normally, when deploying https, it is based on SSL one-way authentication, which means that as long as the client authenticates the server, the server does not need to authenticate the client.
But in some scenarios with higher security, such as banking, finance and other fields, client authentication is usually required. This enables two-way authentication of SSL.
Since the ssl_client_certificate parameter of nginx can only specify one client public key, if you add a client for communication, you will need to reconfigure a server. The
n:1 mode is implemented through the CA's cascade certificate mode. First, generate a set of CA root-level certificates yourself, and then use it to generate a secondary certificate as a client certificate.
At this time, the client private key signature can be verified not only by the corresponding client public key, but also by the public key of the root certificate.
You should be enlightened after seeing this. Here is a brief introduction on how to operate:
1 Preparation work
1.1 Openssl directory preparation
General situation The configuration files of openssl are all in this directory /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 configuration preparation
Modify openssl configuration
vi /etc/pki/ tls/openssl.cnf
Comment out this sentence and replace it with the following sentence
#default_ca = CA_default default_ca = CA_linvo
Copy the entire part of [CA_default] and change it to the name above [CA_linvo]
Modify the following parameters inside:
dir = /etc/pki/ca_linvo certificate = $dir/root/ca.crt private_key = $dir/root/ca.key
Save and exit
2 Create CA root certificate
生成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
The generated root certificate files are all in /etc/pki/ Under the ca_linvo/root/ directory
Note: When creating a certificate, it is recommended that the length of the certificate password is >= 6 characters, because the Java keytool tool seems to have requirements for it.
3 Create server certificate
生成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
Instructions:
1. The crt generated here is the cascade certificate under the ca root certificate just now. In fact, the server certificate is mainly used for configuration. Normal one-way https, so you can do it without using cascade mode:
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. The -days parameter can set the validity period of the certificate as needed, for example, the default is 365 days
4 Create client certificate
生成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
Note:
1. You must use cascading certificates here, and you can repeat this step to create multiple sets of client certificates
2. You may encounter this when generating crt The following error is reported:
openssl TXT_DB error number 2 failed to update database
You can refer to here for operation.
I am using method one, which is to configure nginx with unique_subject = no
5 in index.txt.attr
Only the key parts of the server segment are listed here:
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 Test
6.1 Browser test
Due to two-way authentication, accessing the https address directly through the browser will result in a 400 Bad Request ( No required SSL certificate was sent), the client certificate needs to be installed on the local machine.
The certificate installed on windows needs to be in pfx format, also called p12 format. The generation method is as follows:
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
Then double-click it in windows to install it. During the installation, you will be prompted to enter the time to generate the certificate. Password set.
After the installation is successful, restart the browser and enter the URL to access. The browser may prompt you to select a certificate. Just select the certificate you just installed.
At this time, some browsers will prompt the user that the certificate is not trusted, the address is not secure, etc. This is because our server certificate is issued by ourselves, not by a real authoritative CA organization (usually very Expensive~), just ignore it.
6.2 PHP curl test
Only the key curl parameters that need to be set are listed here:
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; }
The verification failed, and the following information will be in the nginx error log
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 soap test
First you need to build the client's pem format certificate. You can also use the openssl command, but because we already have crt and key, manual merging is also very simple:
Create a new file and copy the base64 content (including these two dividing lines) between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- in crt. , then copy the content between -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- in the key, and then save it as client.pem. .
In fact, if it is more trouble-free, you can directly merge the two files with the following command:
cat /etc/pki/ca_linvo/client/client.crt /etc/pki/ca_linvo/client/client.key > /etc/pki/ca_linvo/client/client.pem
With the pem file, you can use the built-in SoapClient in php to call it. The constructor needs to set the second parameter :
$header = array( 'local_cert' => CLIENT_PEM, //client.pem文件路径 'passphrase' => CRT_PWD //client证书密码 ); $client = new SoapClient(FILE_WSDL, $header); //FILE_WSDL为要访问的https地址
The last blog mentioned that if local_cert is set to a remote path, an error will be reported. It seems that the client certificate is not used when obtaining the wsdl for the first time. The wsdl needs to be kept as a local file. Call;
But this time there was no problem in the test. There is no need to save it as a local file, just get it remotely.
I originally thought there was a problem with the previous certificate, but I can still use the previous set of certificates, which is very strange~~~~~
The above is the detailed content of How to implement https two-way authentication in php. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.
