[PHP-NOTES] note 130602 added to function.openssl-verify

[email protected] ("[email protected]") Mon, 05 Jan 2026 05:09:39 +0000
Newsgroups php.notes
Message-ID <[email protected]>
PHP is the most efficient language for handling web requests. I have tested that PHP's OpenSSL library can decrypt data encrypted by JS using AES, OAEP, and EC-DH, and can also verify data signed by JS using HMAC and RSA-PKCS#1.5. However, it cannot verify data signed by JS using EC-DSA or RSA-PSS. Verifying data signed with EC-DSA and RSA-PSS is necessary. However, PHP's OpenSSL library still does not support verifying EC-DSA and RSA-PSS signatures.

// JS EC-DSA sign
crypto.subtle.generateKey(
	{
		name: 'ECDSA',
		namedCurve: 'P-256'	// P-521 corresponds to secp521r1, P-384 corresponds to secp384r1, p-256 corresponds to prime256v1
	},
	true,
	['sign', 'verify']
).then(pair => {
	return {
		publicKey: crypto.subtle.exportKey('spki', pair.publicKey),
		signature: crypto.subtle.sign(
		{
			name: 'ECDSA',
			hash: {
				name: 'SHA-1' // or SHA-256, SHA-384, SHA-512
			}
		},
			pair.privateKey,
			(new TextEncoder()).encode('test data')
		)
	};
}).then(data => {
	// await crypto.subtle.verify(...) is true;
	// convert data.publicKey ArrayBuffer to PEM publicKey and encodeURIComponent it;
	// convert data.signature ArrayBuffer to base64 string;
	// send data object to PHP
});
// PHP receives the above data and executes openssl_verify
openssl_verify(
	base64_decode($_POST['signature']),
	'test data',
	urldecode($_POST['publicKey']),
	OPENSSL_ALGO_SHA1 // or OPENSSL_ALGO_SHA256, OPENSSL_ALGO_SHA384, OPENSSL_ALGO_SHA512
);
// result: -1

// JS RSA-PSS sign
crypto.subtle.generateKey(
	{
		name: 'RSA-PSS',
		modulusLength: 2048,
		publicExponent: new Uint8Array([1, 0, 1]),
		hash: 'SHA-256' // or SHA-1, SHA-384, SHA-512
	},
	true,
	['sign', 'verify']
).then(pair => {
	return {
		publicKey: crypto.subtle.exportKey('spki', pair.publicKey),
		signature: crypto.subtle.sign(
			{
				name: 'RSA-PSS',
				saltLength: 32
			},
			pair.privateKey,
			(new TextEncoder()).encode('test data')
		)
	};
}).then(data => {
	// await crypto.subtle.verify(...) is true;
	// convert data.publicKey ArrayBuffer to PEM publicKey and encodeURIComponent it;
	// convert data.signature ArrayBuffer to base64 string;
	// send data object to PHP
});

// PHP receives the above data and executes openssl_verify
openssl_verify(
	base64_decode($_POST['signature']),
	'test data',
	urldecode($_POST['publicKey']),
	OPENSSL_ALGO_SHA256 // or OPENSSL_ALGO_SHA1, OPENSSL_ALGO_SHA384, OPENSSL_ALGO_SHA512
);
// result: -1, but RSA-PKCS#1.5 is OK
----
Server IP: 206.189.2.9
Probable Submitter: 123.121.7.59
----
Manual Page -- https://php.net/manual/en/function.openssl-verify.php
Edit        -- https://main.php.net/note/edit/130602
Del: integrated  -- https://main.php.net/note/delete/130602/integrated
Del: useless     -- https://main.php.net/note/delete/130602/useless
Del: bad code    -- https://main.php.net/note/delete/130602/bad+code
Del: spam        -- https://main.php.net/note/delete/130602/spam
Del: non-english -- https://main.php.net/note/delete/130602/non-english
Del: in docs     -- https://main.php.net/note/delete/130602/in+docs
Del: other reasons-- https://main.php.net/note/delete/130602
Reject      -- https://main.php.net/note/reject/130602
Search      -- https://main.php.net/manage/user-notes.php