About the end of PHP encryption and decryption to ECDH (API security enhancement article 3)

  ecdh, php

In fact, the first two were tossed and turned just to force out two things:

  • Symmetric encryption and decryption, typical algorithms are AES, DES, 3DES, etc
  • Asymmetric encryption and decryption, typical algorithms are RSA, DSA, ECDH, etc

However, I know that people hate such things as “elliptic curve”, “prime number”, “prime number” and so on when reading such articles. I can’t understand, understand or memorize them anyway, so I simply don’t write these things, don’t write them at all, and don’t put any pressure on them (however, in fact, I’ve memorized them. I’ve been working on linear algebra recently, so I’m slightly more sensitive to mathematics than before).

After writing here, some unruly and php muddiers thought they had mastered high technology. They took two libraries off github and ran around. After running test, they began to pretend to be forced everywhere, claiming to be proficient in symmetric encryption algorithm and asymmetric encryption algorithm. Especially during the interview, they went up to fool the interviewer. If they were fooled, they would need 50,000, but not 5,000. However, what I want to tell you is that you should continue to look down, so that when you are in the interview, if you are fooled, you can ask for 80,000 yuan, if you are not fooled, you can also ask for a minimum of 8,000 yuan. That’s 3,000 more than the original 5,000! Besides, the guide I provided is still free!

Today we started from a practical need, for example, you are an API developer (of course, as a small company with only a dozen people, you still have to work part-time in operation and maintenance, but the salary is only based on develoPMent, and the operation and maintenance work is your friendly sponsorship to the boss). then the boss and pm asked you a more serious question, which probably means “the company’s project is a very awesome project, and the company will be listed in a year’s time. you must encrypt the data so that neither BAT nor TMD can copy us! Then you can buy a car and a house! ” , you said very recognized. Since you have read my previous two articles and the boss has repeatedly stressed that “we are a cow force project and will be listed sooner or later”, you are prepared to use high-security asymmetric encryption to solve this problem.

The specific method is that the server generates a pair of public and private keys, and then generates a pair of public and private keys to be shared by all clients. For example, the user logs in to the API, and the interface document is roughly as follows:

API : https://www.so.com/api/user/login
PROTOCOL : 将数据以JSON形式,全部放入到http body体中,key叫做mzip
DATA : {
  'username' => 'xitele',
  'password' => 'qiangdadaoniyongyuancaibuchulaishiduoshao'

Then the client executes the login pseudocode as follows:

var username string = 'xitele'
var password string = md5('123456')
// 将数据生成json
var data = jsonize( hashMap(
  'username' : username,
  'password' : password
) )
// 用服务器公钥,将数据加密
var encryptData = RSA.encrypt( '服务端的公钥', data )
// 再次封装数据为json
var lastJson = jsonize( hashMap(
  'mzip' => encryptData
) )
// 提交数据
http.post( 'https://www.so.com/api/user/login', lastJson, function() {
  // ... ... do something ...
} )

The server is implemented in the best language in the world, so the code looks familiar to you:

$jRawData = file_get_contents( 'php://input' );
$aRawData = json_decode( $jRawData, true );
// 使用服务器私钥,对mzip中的加密数据进行解密
$jDecryptData = RSA::decrypt( '服务器的私钥', $aRawData['mzip'] );
// 解密后的数据实际上就是 {"username":"xitele","password":"e10adc3949ba59abbe56e057f20f883e "}
$aDecryptData = json_decode( $jDecryptData, true );
// 进入到我们最熟悉的增删改查流程!
$pdo = new PDO();
$sth = $pdo->prepare( "select * from user where username=:username" );
$sth->bindParam( ':username', $aDecryptData['username'], PARAM_STR );
$aUser = $pdo->fetch();
if ( $aUser['password'] != $aDecryptData['password'] ) {
  echo json_encode( array(
    'code' => 0,
    'msg' => '登陆成功'
  ) );
else {
  echo json_encode( array(
    'code' => 10002,
    'msg' => '登陆失败'
  ) );

After going online, it was found that there was no big problem. It was obvious that the server CPU load was extremely high and the client felt a little stuck. Obviously, the CPU consumption of asymmetric encryption has become a bottleneck. So you asked your boss to apply for the service area fee. The boss said on the spot that he understood it very well. With a wave of his hand, he gave you 300 yuan and said that he was free to squander it, upgrading the server to the most awesome server.

Of course, after learning from me for such a long time, you should immediately realize what 300 yuan means. 300 yuan at most means two sets … …

Of course, API was also able to account for it. The whole line was downgraded to AES symmetry. The CPU came down in an instant, and it was not unusable .. …

Of course, it should still be possible to set up a five-member bureau for 300 yuan. Apart from you and me, we will also pull up the post with Laozhao and finally bring Chen Xu. In addition to eating, the bureau will discuss the solution to this problem.

After the game, I mysteriously told you, “This is very simple. Let me tell you, your server randomly generates a key for AES symmetric encryption first, then encrypts it with the RSA public key of the client and transmits it to the client. The client decrypts it with its own RSA private key to obtain the AES symmetric key, and then uses the AES symmetric key for subsequent encryption and decryption. Then you can set a valid period for the AES key, for example, five minutes. After expiration, you can apply for a new AES key again using the above process! In this way, not only the security of AES key is guaranteed, but also the performance problem can be solved! “

After such a long foreshadowing, the key point of today’s discussion can finally be drawn out: key agreement/exchange! This is our core topic today.

First, let’s talk about why key negotiation and exchange are such things. In fact, it is to avoid the security problems caused by the hijacking of key transmission on the network. The subtext of the first two sentences is “there is a kind of telepathic solution in this world that you can know what I want to tell you even if I don’t tell you.”

The following schemes are commonly used for key agreement exchange:

  • Using RSA and other asymmetric encryption technologies for exchange, that is, the 300-block local scheme
  • Using exchange algorithms that specifically serve the needs of key exchange, such as DH algorithm, the full name is Diffie-Hellman key exchange. Diffie and Hellman are the names of two uncles respectively (note, these two are mathematicians). They developed this algorithm together. DH algorithm appeared before RSA.

Among them, the scheme using asymmetric encryption is probably what I said earlier, and the pseudo code has already been shown. So what exactly is DH?

Let’s play a relatively simple number game:

元首:9 * 300 = 2700
古德里安:3 * 900 = 2700

Both sides have already obtained the same figure of 2700 at the same time by merely confirming their eyes from a distance and saying one word (exchanging 300 and 900 with each other). So, 2700 is the key that encrypts the data when the two parties communicate later. Similarly, both parties can calculate an expiration time for this key, for example, five minutes later, and then negotiate a new one after expiration! Moreover, even if other people knew that both sides chose 100, they also knew that the head of state passed 900 to guderian and that guderian wore 300 to the head of state, but there was no use because he still did not know what the key (i.e. 2700) the other side finally used was.

Of course, it is not so simple for the real DH algorithm to select public numbers and random numbers in reality, and the two parties will not do multiplication as easily and simply as in the above example when finally calculating this key.

I won’t write about the calculation of specific people. It’s everywhere on the Internet anyway, and whether I write it or not, you won’t look at it anyway. After all, it’s something mathematicians want to do.

In front of RSA’s library, I took it from github and test it, so RSA will not demonstrate it. However, DH’s let’s grab one from github and play to verify the simple theory we just talked about.

A DH library of PHP, GITHUB link:https://github.com/jcink/diff …

require_once 'diffie-hellman.php';
$dh = new DiffieHellman();

Save the above code as index.php, and then PHP index.php 32 will execute it. The result is as follows, you can feel it:

We see that this library has printed a log incidentally. As a vast number of mud legs that never study the bottom layer, we only need to pay attention to the last line “Shared Key: 101451040”, which is the key negotiated between the server and the client, which means that 101451040 can be used to encrypt and decrypt the data in the communication process of the later API.

Well, the above is DH algorithm. In fact, those friends in the circle should have known when they saw DH in today’s title. This idiot has been in Amway ECDH in WeChat every day. Today, he finally saw DH with two letters, and finally he has some eyebrows. Is it spicy? I am in Amway every day. What exactly is ECDH?

The specific principle is how to return a responsibility, anyway, I can’t even memorize it this time. However, you can simply think that ECDH is an upgraded version of DH, after all, there are two more letters. In fact, ECDH is a combination of ECC algorithm and DH algorithm. It’s a mother’s egg, and an ECC comes out specially. Okay, okay, just forget I said it.

Then it’s still the old routine. We’ll grab a library from github and simply run test, so that we can go out and pretend to demand 80,000 salaries. Portal:https://github.com/Querdos/EC …

require_once './autoloader.php';
use Querdos\lib\ECDHCurve25519;

$xitele   = new ECDHCurve25519();
$gudelian = new ECDHCurve25519();

$xitele->computeSecret( $gudelian->getPublic() );
$gudelian->computeSecret( $xitele->getPublic() );

// shareKey1 和 shareKey2 就是协商出来的密钥
$shareKey1 = $xitele->getSecret();
echo $shareKey1.PHP_EOL;
$shareKey2 = $gudelian->getSecret();
echo $shareKey2.PHP_EOL;

// 我们用gmp cmp来对比是否为同一个密钥
if ( 0 == gmp_cmp( $shareKey1, $shareKey2 ) ) {
  echo "一样".PHP_EOL;
else {
  echo "不一样".PHP_EOL;

// 除此之外,这个ecdh库比dh那个库多了一个验证数据签名验证,可以检验数据是否被篡改!
$msg = "hello world";
$signature = $xitele->signMessage( $msg );
if ( $gudelian->verifySignature( $signature, $xitele->getPublic(), $msg ) ) {
  echo "验证数据签名成功".PHP_EOL;
else {
  echo "验证数据签名失败".PHP_EOL;

Save the code as index.php, and PHP index.php’s execution results are shown in the following figure:

From the above code, we can see that we can directly recite a conclusion, that is, DH and ECDH can both realize key agreement exchange, but ECDH can also sign the data, and the other party can check and sign the data, so as to judge whether the data has been tampered with during transmission!

Well, the long-cherished ECDH has finally entered the talk! I won’t talk about this again in the group in the future. I wish you happiness.

Recently, we opened a WeChat public number: High Performance API Community. All articles were posted here first.