PHP OpenSSL encryption extended learning (2): asymmetric encryption

Time:2021-12-1

In the last article, we learned some relevant theoretical knowledge about symmetric and asymmetric encryption, and also learned to use OpenSSL for symmetric encryption. Today, we will go further and learn how to implement asymmetric encryption in OpenSSL.

Generate private key

Through the previous study, we know that asymmetric encryption requires a public key and a private key respectively. Let’s first generate a private key, that is, a key stored on our side. Please remember that the private key cannot be given to others at any time!

$config = array(
    "Private_key_bits" = > 4096, // specify how many bits should be used to generate the private key
);

$res = openssl_ pkey_ new($config); //  Generate private key based on configuration information

openssl_ pkey_ export($res, $privateKey); //  Converts the exportable representation of a key to a string
var_dump($privateKey); 
// -----BEGIN PRIVATE KEY-----
// MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDFMLW+9t3fNX4C
// YBuV0ILSyPAdSYVXtE4CLv32OvNk9yQZgF2nL/ZuIbBGRcYo2Hf5B31doGrAFDGu
// NoTR+WA7CBjKROFr/+yValsMFIeiKNtttWMkmBciysDJoEoyd6wjDD+kcHQdoJVo
// ……
// -----END PRIVATE KEY-----

A very simple function OpenSSL_ pkey_ New (), which receives a parameter that is configurable and optional. The generated result is a private key handle, which is not what we can read directly, so we use OpenSSL again_ pkey_ Export() to extract an exportable string.

The content in the comment is the private key information we generated. Generally, there will be more private key information, so the following content is omitted.

Extract public key

The next step is to generate the public key. In fact, the public key is extracted from the private key. Therefore, when we use encryption and decryption, we can use private key or public key to operate with each other.

$publicKey = openssl_ pkey_ get_ details($res); //  Extract public key information
var_dump($publicKey);
// array(4) {
//     ["bits"]=>
//     int(4096)
//     ["key"]=>
//     string(800) "-----BEGIN PUBLIC KEY-----
//   MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtOIImDdS0W0vAr5Ra1+E
//   hR2AJwQQwxntYKgTku8EmJRBX2vU+x8th8W8SnoGiVM/sOItG0HIe4Egf1UxoZHt
//   gI6r+jpAp7JbTN0sD/VTPDE09F21+hFGjIVBqrkcLPjuEbf7+tjmgAx8cG8WLGId
//   G8Hsub70kRANKJe1bCXIBUggRFk0sQGllxA/hxiG5wANqHTrdpJgJba+ahSi2+4H
//   UWnyCV1O3AaPyz6a12HNUsG4Eio/tWv/hOB9POt6nAqwPHuIbhp56i5bv1ijMJZM
//   jwRen5f/kwdZ01Ig2fi0uBoTR2y/EEaus7xBYpF/gGzZ/uM7cNUXcDyG5YluM/4R
//   MEv4msPMVGB72izItED+C6Cqftxl98iBFRDc+PISFbRSgOU/HsuBhKkM5SYzyi3I
//   Ypaej25++qLPqcA+EDr3JNDhNZ0GOhofCRtPq4dsr7iLLLRnZ0TnhIYe9wAbmO49
//   uthABNBkM54bG+omOfY4Bkn5n39CKpELbhIiXgOd+lA684XUS/2Aw3Dvelc9Gbag
//   oIFvb/wljPYsd0Zmd64CXBpTWbfwXC8K4vCKvFLjytcz2Yp4T6fVjbLT5RA6u8su
//   E0WwE4QTFNKhnM5OvfiMN+NMc3Y/esVfcin3eyvotdz4N6Tt45dkybkf6aQE3Scg
//   E/JBLIEEA+gjGTveY4cNUiECAwEAAQ==
//   -----END PUBLIC KEY-----
//   "
//     ["rsa"]=>
// ……

$publicKey = $publicKey['key'];

Using OpenSSL_ pkey_ get_ The content extracted by details () contains a lot of content. However, the most important thing we need is the public key under the key.

Let’s go back and have a good look at the contents of the public and private keys. Are they the same as the public and private keys in the HTTPS certificate we applied for, and also the same as the local key certificate generated by using the OpenSSL command line in the system. They are the same thing in themselves, but they are applied differently in different scenarios. In addition to the asymmetric encryption key, the HTTPS certificate also contains CA information. If the CA does not pass, the browser will also consider the certificate invalid. Therefore, it is not allowed for us to use the self generated certificate as the HTTPS certificate. The generated by itself will generally be used for SSH password free login or GitHub password free code warehouse operation.

Encrypt and decrypt data

Well, the public key and private key have been generated, so we need to perform the most important encryption and decryption operations.

$data = 'test asymmetric encryption';

//Public key encrypted data
openssl_public_encrypt($data, $encrypted, $publicKey);
var_dump($encrypted);
// string(512) "��E��2��~��\d����q�O�=(��Y���3L����0�,�J����s�V��V ߬ G~'�20���@��6�d�����#Z]�.���1��a��r� ̹ D @ - s > ܬ ��
//YXZ # L # c ` RJ 睅 nx @{7 睅 QY 睅 ʲ nv�o§�@�@,�n&���I�~ ǧ �z6���oe!8,T�����; җ �6� [email protected] ��f����S]��!����2�b��+O ګ ��o�

Here, we use the most standard public key encryption and private key decryption to test. In fact, the reverse is also possible. OpenSSL provides us with public key encryption and decryption and private key encryption and decryption functions respectively.

As shown in the previous article, the other party obtains our public key, then encrypts the data and transmits it. We decrypt the data through our own private key to obtain the original text. We can also obtain the other party’s public key, encrypt the returned data and transmit it to the other party, and then the other party decrypts it with its own private key to obtain the original data we transmitted to it.

HTTPS obtains the public key through the certificate issued by ca. the browser requests data to be transmitted to the server through public key encryption. The server also sends ciphertext data to the browser client through the same principle. Therefore, in the process of data transmission, the transmission using HTTPS will be more secure. Even if it is intercepted, the other party does not have the key provided by the certificate to decrypt. This is why all apps and applet applications now require HTTPS. Of course, if we do website development, we’d better use HTTPS. Even Baidu’s collection of HTTPS has been adjusted accordingly.

Signature and verification

Next, let’s touch on the concept of signature. When two ends communicate, how do we know that the data currently transmitted must be sent from the opposite end? Has any hacker tampered with it? This can be verified through the signature mechanism.

//Generate signature using private key
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
var_dump($signature);
// ��B�N�WM!TN�c�F�/��,5�|���%��c~O)"
// ��      >��)y�fn��q��}
//                       �`
//                         �z��{��_D�s`�����|y�,g>R�D��%�
//                                                       �g ͯ 0�@Λ|��|z}���bZI2,����~Q_ I LW ~ |g & |f | EQ | s d | L | BC'd | 8: Z | 9] C | KD ~ f96 | s 謃 0 ɋ Y > (t | s} 1 謃t)
//                                                                                                                                                                    �!��!!�Lj�

We use OpenSSL_ Sign () to generate a private key signature of the original data, and then OpenSSL can be used_ Verify() verifies whether the data signatures are consistent through the public key.

When using, the sender generates a signature through its own private key. Because the signature content is garbled, we can base it 64_ Encode() and then pass it to the receiver together with the encrypted data. Then the receiver uses the public key to verify whether the original data has been tampered with according to the signature content.

//Sender signature
$resquestSign = base64_encode($signature);

//Suppose data is sent through a network request
// ……
//Received and obtained signature and original data
// $signature = $_POST['sign'];
// openssl_private_decrypt($_POST['data'], $data, $privateKey); 

$responseSign = base64_decode($signature);
//Verify that the data has not been tampered with
$r = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
var_dump($r);
// int(1)

//Assumptions are tampered with
$data = 'I have been modified';
$r = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
var_dump($r);
// int(0)

summary

Does today’s content feel much more complex than symmetric encryption. In particular, the newly introduced concept of signature, in fact, many certificate related contents will be related to data signature. In other words, the seemingly simple HTTPS, in fact, OpenSSL on the browser and server side has helped us do a lot of things, far more than you go to the CA to apply for a set of certificates and then match them in nginx. Then, next, we will learn the content related to the generation of certificates. Fasten your seat belt and keep the car racing.

Test code:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84OpenSSL%E5%8A%A0%E5%AF%86%E6%89%A9%E5%B1%95%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%BA%8C%EF%BC%89%EF%BC%9A%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86.php

Reference documents:

https://www.php.net/manual/zh/function.openssl-pkey-new.php

https://www.php.net/manual/zh/function.openssl-pkey-get-details.php

https://www.php.net/manual/zh/function.openssl-pkey-export.php

https://www.php.net/manual/zh/function.openssl-public-encrypt.php

https://www.php.net/manual/zh/function.openssl-private-decrypt.php

https://www.php.net/manual/zh/function.openssl-sign.php

https://www.php.net/manual/zh/function.openssl-verify.php

Official account: hard core project manager

Add wechat / QQ friends: [xiaoyuezigonggong / 149844827] get free PHP and project management learning materials

Tiktok, official account, voice, headline search, hard core project manager.

Station B ID: 482780532