First, the concepts of symmetric and asymmetric encryption are explained.

Symmetric encryption: In a single-key cryptosystem, the same key can be used to encrypt and decrypt information at the same time. This encryption method is called symmetric encryption, also known as single-key encryption.

Asymmetric encryption: an asymmetric encryption algorithm requires two keys: a publickey and a privatekey. The public key and private key are a pair. If the public key is used to encrypt data, only the corresponding private key can be used to decrypt data. Because encryption and decryption use two different keys, the algorithm is called asymmetric encryption.

Symmetric encryption features:

  1. Symmetric encryption algorithm has the advantages of open algorithm, small computation, fast encryption speed and high encryption efficiency.
  2. But the drawback of symmetric encryption is that before data can be transmitted, the sender and receiver must agree on the secret key, and then enable both parties to keep the secret key.
  3. If one party divulges the secret key, security is not guaranteed;
  4. If a large number of secret keys are introduced to improve security, the management of secret keys will become huge and complicated.

Asymmetric encryption features:

  1. The strength of the algorithm is complex, the decryption is difficult, and the security is guaranteed.
  2. The encryption and decryption speed is not as fast as that of symmetric encryption and decryption.

Thoughts brought about

The advantages of symmetric encryption and asymmetric encryption are integrated, referring to the implementation ideas of HTTPS encryption and decryption, and SSL(Secure Scoket Layer) is encapsulated by ourselves.

Specific implementation ideas are as follows:

The APP side initiates the request and the server side returns the data encryption:

  1. Generate a random 15-digit alphanumeric string as the AES128 key for this request
  2. The request parameters are encrypted using AES128 encryption keys to obtain the request parameters ciphertext
  3. Encrypts the key in 1 using the RSA public key specified on the front and back ends
  4. Take the ciphertext of 23 as the parameter to initiate a request
Plaintext {key: miwenKey, data: miwenData} Actual request {data: "Base64 encoded string of the above JSON"}Copy the code

My example code is PHP, other languages can refer to my implementation ideas:

Business code encapsulation

  1. Server return data code:
public function myMessage($data.$status = "success")
{
    $aes = new AesSecurity(); Symmetric encryption
    $rsa = new RsaService(); // Asymmetric encryption

    //1, a random alphanumeric string of digits is generated as the AES128 key of this request
    $aes_key = randomkeys(16);
    //2. Use the preceding key to perform AES128 encryption on the request parameters to obtain the ciphertext of the request parameters, and obtain the ciphertext miwenData
    $miwenData = $aes::encrypt(json_encode($data),$aes_key);
    //3. Use the RSA public key specified on the front and back ends to encrypt the key in 1 to obtain the miwenKey
    $miwenKey = $rsa->publicEncrypt($aes_key);
    / / 4. Base64 transcoding
    $data = base64_encode(json_encode([
        'key'= >$miwenKey.'data'= >$miwenData,]));return Response::json($data.$this->getStatusCode(),$header= []); }Copy the code
  1. Server parsing data code:
public function aesData(BaseFormRequest $request)
{
    // Decrypt data
    $data = $request->post('data'.' ');
    $data = json_decode(base64_decode($data),true);

    $key = $data['key'];
    $data = $data['data'];

    $aes = new AesSecurity(); Symmetric encryption
    $rsa = new RsaService(); // Asymmetric encryption
    //1. Use the RSA private key specified on the front and back ends to decrypt and obtain the miwenKey (because the client uses the public key for encryption, the server uses the public key for decryption)
    $miwenKey = $rsa->privateDecrypt($key);
    //2. Use the preceding miwenKey to perform AES128 decryption on the data parameter of the request to obtain the ciphertext miwenData
    $miwenData = $aes::decrypt($data.$miwenKey);
    //3. Convert json strings into arrays
    $data = json_decode($miwenData.true);

    //todo turns on timestamp verification
    $time = $data['time'];
    // Operations cannot continue if the verification fails after 30 seconds
    if ($time<time()-30) {throw new Exception('Access timed out, operation not allowed');
    }

    return $data;
}
Copy the code

The parsed parameters are obtained from the business layer Controller

public function create(LoginRequest $request)
{
    // Decrypt data
    $data = $request->aesData($request);

    $name = $data['name'];
    $password = $data['password']; ...}Copy the code

Tools:

  1. AES symmetric encryption

      
/** * [AesSecurity AES encryption, PHP7.1 supported] */
class AesSecurity
{
    /** * [encrypt AES encryption] *@param[type] $input [data to be encrypted] *@param[type] $key [encryption key] *@return[type] [encrypted data] */
    public static function encrypt($input.$key)
    {
        $data = openssl_encrypt($input.'AES-128-ECB'.$key, OPENSSL_RAW_DATA);
        $data = base64_encode($data);
        return $data;
    }
    /** * [decrypt AES decryption] *@param[type] $sStr [data to decrypt] *@param[type] $sKey [encryption key] *@return[type] [decrypted data] */
    public static function decrypt($sStr.$sKey)
    {
        $decrypted = openssl_decrypt(base64_decode($sStr), 'AES-128-ECB'.$sKey, OPENSSL_RAW_DATA);
        return $decrypted; }}Copy the code

Generate an RSA key reference link

  1. RSA asymmetric encryption core code:

      

namespace App\Services;

use Exception;

class RsaService
{
    /** * public key *@var* /
    protected $public_key;


    /** * private key *@var* /
    protected $private_key;


    /** * Public key file path *@var* /
    protected $public_key_path = '.. /keys/rsa_public_key.pub';


    /** * pkCS8 is used only to facilitate program resolution of the private key file path *@var* /
    protected $private_key_path = '.. /keys/rsa_private_key_pkcs8.pem';


    /** * / RsaService constructor@paramBool $type Default private key encryption */
    public function __construct($type = true)
    {
// if ($type) {
            $this->private_key = $this->getPrivateKey();
// } else {
            $this->public_key = $this->getPublicKey();
/ /}
    }


    Openssl_pkey_get_private This function can be used to determine whether the private key is available, available, return resources *@return bool|resource
     */
    private function getPrivateKey()
    {
        $original_private_key = file_get_contents(__DIR__ . '/.. / ' . $this->private_key_path);
        return openssl_pkey_get_private($original_private_key);
    }


    Openssl_pkey_get_public This function can be used to determine whether the private key is available, available, and return resources *@return resource
     */
    public function getPublicKey()
    {
        $original_public_key = file_get_contents(__DIR__ . '/.. / ' . $this->public_key_path);
        return openssl_pkey_get_public($original_public_key);
    }


    /** * private key encryption *@param $data
     * @paramBool $serialize is so that whether you're passing a string or an array, you can convert it to a string *@return string
     * @throws \Exception
     */
    public function privateEncrypt($data.$serialize = true)
    {

        $data = substr($data.0.30);
        openssl_private_encrypt(
            $serialize ? serialize($data) : $data.$encrypted.$this->private_key
        );
        if ($encrypted= = =false) {
            throw new \Exception('Could not encrypt the data.');
        }
        return base64_encode($encrypted);
    }


    /** * private key decryption *@param $data
     * @param bool $unserialize
     * @return mixed
     * @throws \Exception
     */
    public function privateDecrypt($data.$unserialize = true)
    {
        openssl_private_decrypt(base64_decode($data),$decrypted.$this->private_key);

        if ($decrypted= = =false) {
            throw new \Exception('Could not decrypt the data.');
        }

        return $unserialize ? unserialize($decrypted) : $decrypted;
    }


    /** * Public key encryption *@param $data
     * @paramBool $serialize is so that whether you're passing a string or an array, you can convert it to a string *@return string
     * @throws \Exception
     */
    public function publicEncrypt($data.$serialize = true)
    {
        openssl_public_encrypt(
            $serialize ? serialize($data) : $data.$encrypted.$this->public_key
        );
        if ($encrypted= = =false) {
            throw new \Exception('Could not encrypt the data.');
        }

        return base64_encode($encrypted);
    }


    /** * Public key decryption *@param $data
     * @param bool $unserialize
     * @return mixed
     * @throws \Exception
     */
    public function publicDecrypt($data.$unserialize = true)
    {
        openssl_public_decrypt(base64_decode($data),$decrypted.$this->public_key);

        if ($decrypted= = =false) {
            throw new \Exception('Could not decrypt the data.');
        }

        return $unserialize ? unserialize($decrypted) : $decrypted; }}Copy the code

Example of RSA asymmetric encryption algorithm

The code that generates the secret key

Step 1: generate the private key. Here we specify the length of the private key as1024Openssl genrsa -out rsa_private_key.pem Indicates that the encryption and decryption takes longer1024Openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pub Convert the private key to PKCS8 format. Openssl pkcs8-topk8-inform PEM -in rsa_private_key. PEM -outform PEM -nocrypt-out rsa_private_key_pkcs8.pemCopy the code

Welcome your guidance

Welcome the nuggets to recommend my article

Welcome everyone to like, leave a comment! One Piece king here to express thanks!