Mastering PHP Data Encryption with OpenSSL and SM4: A Practical Guide

This guide explains fundamental data encryption concepts, introduces PHP's openssl_encrypt function, compares common encryption modes, shows how to generate keys and initialization vectors, and provides a complete SM4‑CBC implementation with sample code and practical security precautions.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Mastering PHP Data Encryption with OpenSSL and SM4: A Practical Guide

Data Encryption Basics

Encryption converts plaintext into ciphertext using an algorithm, a secret key, and often an initialization vector (IV). Only parties possessing the correct key and IV can recover the original data.

PHP openssl_encrypt Overview

The openssl_encrypt function encrypts data with OpenSSL. Its signature is:

/**
 * openssl_encrypt — encrypt data using OpenSSL
 * @param string $data   Data to encrypt
 * @param string $method Encryption algorithm (e.g., "AES-128-CBC", "SM4-CBC")
 * @param string $key    Secret key (binary or hex‑encoded)
 * @param int    $options Encryption options (e.g., OPENSSL_RAW_DATA)
 * @param string $iv     Initialization vector (length must match cipher)
 * @return string        Ciphertext (binary or base64‑encoded depending on options)
 */
function openssl_encrypt(string $data, string $method, string $key, int $options = 0, string $iv = ''): string {}

Supported Cipher Modes

ECB – encrypts each block independently (no IV, not recommended for most uses).

CBC – chains each block with the previous ciphertext; requires a random IV.

CFB – turns a block cipher into a stream cipher; also uses an IV.

OFB – similar to CFB but does not re‑encrypt the ciphertext.

Key and IV Generation

Keys and IVs should be generated with cryptographically secure random bytes.

$key = openssl_random_pseudo_bytes(16); // 128‑bit key for AES‑128
$hexKey = bin2hex($key); // optional hex representation

$ivLength = openssl_cipher_iv_length('AES-128-CBC');
$iv = openssl_random_pseudo_bytes($ivLength);

SM4‑CBC Encryption and Decryption Example

SM4 is a Chinese national symmetric cipher. The following code demonstrates full encryption and decryption using the SM4-CBC mode.

// 1. Define algorithm
$cipherAlgo = 'SM4-CBC';

// 2. Determine required IV length
$ivLength = openssl_cipher_iv_length($cipherAlgo);
printf("[SM4 IV length]: %s
", $ivLength);

// 3. Generate a random key matching the IV length (binary form)
$keyBinary = openssl_random_pseudo_bytes($ivLength);
$keyHex = bin2hex($keyBinary);
printf("[SM4 key]: %s
", $keyHex);

// 4. Generate a random IV (SM4 uses a 16‑byte IV)
$ivBinary = openssl_random_pseudo_bytes(16);
$ivHex = bin2hex($ivBinary);
printf("[SM4 IV]: %s
", $ivHex);

// 5. Encrypt plaintext
$plaintext = '开源技术小栈';
$encrypted = openssl_encrypt(
    $plaintext,
    $cipherAlgo,
    $keyBinary,
    OPENSSL_RAW_DATA,
    $ivBinary
);
printf("[SM4 encrypted]: %s
", base64_encode($encrypted));

// 6. Decrypt ciphertext
$decrypted = openssl_decrypt(
    $encrypted,
    $cipherAlgo,
    $keyBinary,
    OPENSSL_RAW_DATA,
    $ivBinary
);
printf("[SM4 decrypted]: %s
", $decrypted);

A reusable class can encapsulate the logic:

<?php
declare(strict_types=1);
namespace security;

class SM4Util {
    private const ALGORITHM = 'SM4-CBC';

    public static function encrypt(string $data, string $keyHex, string $ivHex): string {
        return openssl_encrypt(
            $data,
            self::ALGORITHM,
            hex2bin($keyHex),
            OPENSSL_RAW_DATA,
            hex2bin($ivHex)
        );
    }

    public static function decrypt(string $cipher, string $keyHex, string $ivHex): string {
        return openssl_decrypt(
            $cipher,
            self::ALGORITHM,
            hex2bin($keyHex),
            OPENSSL_RAW_DATA,
            hex2bin($ivHex)
        );
    }
}
?>

Precautions

Select the algorithm and mode that meet the required security level (e.g., avoid ECB for sensitive data).

Store keys and IVs securely; never hard‑code them in source code or expose them in logs.

Understand padding requirements of the chosen mode (e.g., PKCS7 for CBC) and set appropriate OPENSSL_RAW_DATA or OPENSSL_ZERO_PADDING flags.

When transmitting ciphertext, encode it (e.g., Base64) to avoid binary‑data corruption.

Conclusion

The openssl_encrypt family provides a flexible interface for symmetric encryption in PHP. By generating cryptographically strong keys and IVs, choosing secure cipher modes such as CBC or GCM, and handling ciphertext encoding correctly, developers can protect data in transit and at rest. The SM4‑CBC example illustrates how to apply a national standard cipher using the same API.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PHPencryptionOpenSSLdata securitycryptographySM4
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.