The previous article introduced the principle of symmetric encryption, but its biggest problem is that the encryption and decryption keys are the same, and can not guarantee that the key can be safely delivered to both sides, even if it is safely delivered to both sides, there will inevitably be "undercover" inside.
Asymmetric encryption
Since symmetric encryption exists, asymmetric encryption is naturally associated with it. The core of asymmetric encryption is that encryption and decryption use different keys. How to use different keys?
For example, I have a money jar that can only be opened by keys. Usually, people can only put their change in the money jar, but only I have the key to withdraw money. Coins placed in the coin storage tank can be regarded as encrypted content, and only with the key can the "encrypted" coins be taken out.
In this way, we can give anybody the key (public key) used for encryption, and we can protect our data safely as long as we keep the decrypted key (private key) ourselves.
There are many asymmetric algorithms: RSA, Elgamal, knapsack, Rabin, D-H, ECC, etc. Let's briefly introduce RSA algorithm.
RSA algorithm
RSA public key encryption algorithm was proposed by Ron Rivest, Adi Shamir and Leonard Adleman in 1977. It was first announced in 1987 when all three of them worked at MIT. RSA is a combination of the initial letters of their three surnames (when is it named after me).
RSA is the most influential public key encryption algorithm at present. It can resist most known cryptographic attacks so far. It has been recommended by ISO as the public key data encryption standard.
RSA Encryption & RSA Decryption Formula
// Note: The plaintext is numeric, and the actual calculation process can be converted by ASCII code. Ciphertext = (plaintext ^ E)% N; // where E and N are our public keys Plaintext= (ciphertext ^ D)% N; // where D and N are our private keys
Compute public key (E), private key (D) and number (N)
Public and private keys are calculated by rigorous mathematical formulas rather than just a few numbers.
1. Prepare two prime numbers P and Q randomly and calculate the product to get N.
N = P * Q;
2, calculate L
L = (P - 1) * (Q - 1); //Graphic decryption technology said that the minimum common multiple after the product needs to be calculated, but the code test is not accurate, who knows the trouble message to tell you?~
3. Compute E (Public Key) to be used by the encryption party.
// E needs to satisfy the following two conditions at the same time 1. 1 < E < L 2. The maximum common number of E and L is one (Euclidean algorithm, these demons, E and L must be mutually prime in order to ensure that private key D can be calculated).
4. Compute D (Private Key) to be used by decryptors
//D needs to satisfy the following formula (E * D) % L = 1; //To ensure that the result is 1, E and L must be mutually prime!!!
The above is the whole calculation process. In order to ensure the security of the data, P and Q will choose very large numbers (1024 bits or larger).
Encryption and Decryption of RSA
The above mentioned methods of encryption and decryption have been mentioned. Let's practice them with specific figures and deepen our understanding.
1. Find N(P*Q)
Assumption: P = 7, Q = 11 (both prime) So: N = P * Q = 7 * 11 = 77
2. Find L ((P-1)* (Q-1))
L = (P - 1) * (Q - 1) = 6 * 10 = 60
3, seek E
1 < E < 60 The maximum common divisor of E and L is one. Let's assume E=23.
4. Calculate D ((E * D)% L = 1)
(23 * D) % 60 = 1; D = 47;
Then I get the public key (E=23,N=77) and the private key (D=47,N=77).
Encryption & Decryption
Let's assume that we need to encrypt numbers: 12
Formula: ciphertext = (plaintext ^ E)% N;
12 ^ 23 % 77 = 6624737266949237011120128 % 77 = 45;
This 45 is our encrypted ciphertext
Decrypt
Formula: plaintext = (ciphertext ^ D)% N;
45 ^ 47 % 77 = 502328880013965819626664594350710696732674427522624682751484215259552001953125 % 77 = 12;
The original text is as follows:12
PHP example
Below is an ex amp le of encryption and decryption implemented by PHP for your reference (because the results of exponential operations are very large, we must use BC Math series functions provided in PHP to calculate)
/** * Counterfeit RSA algorithm * @author zhjx922 */ /** * Judging whether a number is a prime number * @param $num * @return bool */ function isPrimeNumber($num) { $k = 0;//Define Number Variables for ($i = 1; $i <= $num; $i++) { if (bcmod($num, $i) == 0) { $k++;//If the modulus is equal to 0, the number k adds itself. } } if ($k == 2) { return true; } return false; } //Finding the Minimum Common Multiplier function minMultiple($a, $b) { if($b==0) //It must be considered that the divisor cannot be zero. { return $b; } else { $m = bccomp($a, $b) == 1 ? $a : $b; $n = bccomp($b, $a) == 1 ? $b : $a; for($i=2; ; $i++) { $mul = bcmul($m, $i); if(bcmod($mul, $n) == 0) { return $mul; } } } return bcmul($a, $b); } //greatest common factor function maxDivisor($a,$b) { $n = bccomp($a, $b) == 1 ? $b : $a; for($i = $n; $i>1; $i--) { if(bcmod($a, $i) == 0 && bcmod($b, $i) == 0) { return $i; //If echo $i is used here, the output is 432; therefore, the difference between echo and return should be distinguished. } } return 1; } do{ //Random prime number P $p = mt_rand(101, 197); } while(!isPrimeNumber($p)); do{ //Random prime Q $q = mt_rand(101, 197); } while(!isPrimeNumber($q)); $n = bcmul($p, $q); //$l = minMultiple($p - 1, $q - 1); // Tested unavailable $l = bcmul($p - 1, $q - 1); do { $e = mt_rand(2, $l - 1); }while(maxDivisor($e, $l) != 1); $d = 1; while(bcmod(bcmul($e,++$d), $l) != 1) { } echo 'p:' . $p . PHP_EOL; echo 'q:' . $q . PHP_EOL; echo 'n:' . $n . PHP_EOL; echo 'l:' . $l . PHP_EOL; echo 'e:' . $e . PHP_EOL; echo 'd:' . $d . PHP_EOL; echo "public key:e={$e},n={$n}" . PHP_EOL; echo "private key:d={$d},n={$n}" . PHP_EOL; //encryption function encode($e, $n, $string) { $enString = ''; $len = strlen($string); for($i = 0; $i < $len; $i++) { $pow = bcpow(ord($string{$i}), $e); $mod = bcmod($pow, $n); $enString .= pack('L', $mod); } return $enString; } //Decrypt function decode($d, $n, $string) { $deString = ''; $string = unpack('L*', $string); $len = count($string); for($i = 1; $i <= $len; $i++) { $pow = bcpow($string[$i], $d); $mod = bcmod($pow, $n); $deString .= chr($mod); } return $deString; } $startTime = microtime(true); $string = 'Welcome to your attention."Pretend to be a programmer"Public address'; echo "original text:" . $string . PHP_EOL; $encodeString = encode($e, $n, $string); echo "ciphertext:" . $encodeString . PHP_EOL; $decodeString = decode($d, $n, $encodeString); echo "After decryption:" . $decodeString . PHP_EOL; $endTime = microtime(true); echo "Total:" . ($endTime - $startTime) . 's.' . PHP_EOL;
No absolutely secure encryption
There is no way to keep absolute security all the time, especially the commonly used MD5. If your database password is still using the hash result of MD5, don't laugh at people who use the password directly in plain text. Fifty steps laugh a hundred steps.
Recently, Google announced that it has cracked SHA-1. With the improvement of computing power, SHA-256, RSA and so on are also sooner or later.
Welcome to pay attention to my public number, and exchange and study together.~