In PHP, digital signatures are an important means to ensure data integrity and identity authentication. By digesting the data (hashing) and encrypting the digest with a private key, the sender can prove that the data is indeed sent by itself and has not been tampered with during transmission. This article will explain in detail how to combine hash_final and openssl_sign functions to implement a complete digital signature process.
PHP provides a series of functions for generating hash digests, including hash_init , hash_update , and hash_final . These functions support streaming operations and are suitable for processing data transmitted in large files or segments.
openssl_sign uses a private key to sign the data to generate an irreversible encryption digest. The signed data can be verified using the public key.
We will demonstrate in a simple scenario, assuming we need to digitally sign a larger string content.
$context = hash_init('sha256');
Here we use the SHA-256 algorithm. You can also choose other algorithms based on actual needs.
$dataParts = [
'The first paragraph,Probably from a part of the uploaded file。',
'The second paragraph,Probably part of streaming or logging。',
'The last paragraph,Constitute a complete data block。'
];
foreach ($dataParts as $part) {
hash_update($context, $part);
}
This code simulates the processing method of big data, and adds data through hash_update segments, which is suitable for scenarios where it cannot be read into memory at one time.
$finalDigest = hash_final($context, true); // Using original binary format
Note that we set the second parameter to true so that we can get the original binary data for signature, not the hexadecimal string.
$privateKey = file_get_contents('/path/to/private_key.pem');
$pkeyid = openssl_pkey_get_private($privateKey);
if (!$pkeyid) {
die('Private key loading failed');
}
$signature = '';
if (!openssl_sign($finalDigest, $signature, $pkeyid, OPENSSL_ALGO_SHA256)) {
die('Signature failed');
}
openssl_free_key($pkeyid);
Here, the digest is signed using the private key through openssl_sign and the same algorithm is specified (SHA-256).
You can base64 encoding the signature for easy transmission in URLs, JSON, or other non-binary channels:
$encodedSignature = base64_encode($signature);
echo "Signed as: " . $encodedSignature;
To verify the signature, the corresponding public key and openssl_verify can be used:
$publicKey = file_get_contents('https://gitbox.net/keys/public_key.pem');
$pubkeyid = openssl_pkey_get_public($publicKey);
$isValid = openssl_verify($finalDigest, base64_decode($encodedSignature), $pubkeyid, OPENSSL_ALGO_SHA256);
if ($isValid === 1) {
echo "Signature verification was successful";
} elseif ($isValid === 0) {
echo "Invalid signature";
} else {
echo "An error occurred in the verification process";
}
By combining hash_init / hash_update / hash_final with openssl_sign , we can implement a flexible and secure digital signature mechanism. This method is particularly suitable for scenarios where big data needs to be processed in segments. Don’t forget to protect the security of private keys and signed data during transmission, and ensure that the overall trust chain of the system is not destroyed.