Trying to code a PHP equivalent of this C# code. Hashing and Signing of a text value

beautifulcan

New member
Joined
Jun 24, 2025
Messages
2
Programming Experience
Beginner
I have this code block in C# that I am trying to convert to PHP and Java. But already got stuck on PHP

C#:
// code sample given to me as to how the Token is created
var text = "Text to Hash and then Sign";

var store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadOnly);
var certificate = store.Certificates.Single(c => c.Thumbprint == "Whatever-Your-Thumbprint-Is"); // or grab the certificate however you please
var certp = certificate.GetRSAPrivateKey();
    
// Hash the data
var sha1 = new SHA1Managed();
var data = Encoding.Unicode.GetBytes(text);
var hash = sha1.ComputeHash(data);

// Sign the hash
var signedBytes = certp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
var token = Convert.ToBase64String(signedBytes);

It is for an API that I am calling. But when I code it in PHP, it looks to be getting the wrong result in my tests.

I am not too familiar with C#. But the above code, from what I can tell, opens and gets the Private Key, SHA1 hashes the text, then signs it with the private key.

I do the same with PHP, but when I get to pass the token, the API call fails (cuz of the token). I open the Certificate, sha1 hash it, then certificate sign it using SHA1.

PHP:
$certFile = "/location/of/certificate.pfx"; 
$certPassword = "password";

// Load the certificate
$cert = file_get_contents($certFile);
if (!$cert) {
    throw new Exception("Unable to load the certificate");
}

// Load the certificate from file using the passphrase
$pkeyid = openssl_pkcs12_read($cert, $certData, $certPassword);
if (!$pkeyid) {
    throw new Exception("Unable to read the certificate or incorrect password");
}

//validated that the fingerprint of this certificate is the correct and matches
//$fingerprint = openssl_x509_fingerprint($certData['cert'], 'sha1', false);
//if ($fingerprint !== 'Whatever-Your-Thumbprint-Is') throw new Exception("Wrong certificate");

$datatohash = 'Text to Hash and then Sign';
$data = mb_convert_encoding($datatohash, 'UTF-16LE', 'UTF-8'); 

$hash = sha1($data);

$signedBytes = '';
if (!openssl_sign($hash, $signedBytes, $certData['pkey'], OPENSSL_ALGO_SHA1)) {
    throw new Exception("Error signing the hash");
}

$signed_token = base64_encode($signedBytes);

// Extra check to verify the sign
if (openssl_verify($hash, base64_decode($signed_token), $certData['cert'], OPENSSL_ALGO_SHA1)) {
   // signature is correct
} else {
    throw new Exception("Validation Error signing the hash");
}

I am not sure if I misinterpreted the C# code, or if I am failing in the conversion to PHP (probably both? heh).

Any help would GREATLY be appreciated.
 
I don't know PHP APIs that well. Are you absolutely sure that accessing $certData['pkey'] will give you the private key from the certificate?
 
I don't know PHP APIs that well. Are you absolutely sure that accessing $certData['pkey'] will give you the private key from the certificate?

I am absolutely sure that $certData['pkey'] is the valid private key from the certificate. Also the last validation check in PHP I am doing is verifying the signature using the public key and it validates.

Also, maybe I should post this in a php forum? I initially posted here because the source code is C# and I am not too familiar with the language.
 
Also the last validation check in PHP I am doing is verifying the signature using the public key and it validates.

Perhaps it's the way you are sending the token to the API that is issue, and not necessarily the creation of the token.

A quick way to verify if the generated token is correct is to sign the same string both using the C# code and using the PHP code. If the results are different, then it's the token. If the tokens are the same, then it's something about the transmission.
 
What happens when you use these instead: openssl_pkey_get_private() and openssl_pkey_get_public() ?
 
Back
Top Bottom