Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to digitally sign a file in PHP

I made a user table in my DB with different columns for holding users' info. Also I have added two columns public_key and private_key. When a user registers, his info will be inserted to the table. plus I am using:

// Create the keypair
$res=openssl_pkey_new();

// Get private key
openssl_pkey_export($res, $privatekey);

// Get public key
$publickey=openssl_pkey_get_details($res);
$publickey=$publickey["key"];

to create a random key pair and give it to user so that every user has a key pair. I want my users to have digital-signature ability, so when they upload a file they sign it.

I decided to sign a sample file(msg.txt) first to see if I can and then proceed. It looks straight forward:

openssl_pkcs7_sign("msg.txt", "signed.txt", "signing_cert.pem",
array("private_key.pem", "mypassphrase"),
array()
);

The problem is: what are signing_cert.pem and private_key.pem ? I pasted my generated public key in signing_cert.pem and the private one in private_key.pem, but I see this error:

Warning: openssl_pkcs7_sign() [function.openssl-pkcs7-sign]: error getting 
private key in /home/ofathian/public_html/msc/ebook/mine/assymetric-test.php 
on line 40

Any opinion is appreciated.

like image 741
Omidoo Avatar asked Mar 14 '12 18:03

Omidoo


People also ask

How do I digitally sign a PDF using USB token in PHP?

You need to create a client-side module, then calculate the hash of the document on the server, send it along with the client module to the web browser (by including it into the web page) and have the client-side module sign the hash. Then send the hash back to the server.

How can I add digital signature in Tcpdf?

<br />To validate this signature you have to load the <b color="#006600">tcpdf. fdf</b> on the Arobat Reader to add the certificate to <i>List of Trusted Identities</i>. <br /><br />For more information check the source code of this example and the source code documentation for the <i>setSignature()</i> method.


1 Answers

I came to conclusion of why not make my own digital signing function.

digital signing algorithm works like this: first the plain text is hashed then it is encypted by user's private key, then the result is concatenated with the plain text.

pseudo code:

return [input + encrypt(md5(input),private_key)]

For verifying: Input is splitted to plain text and signature. then signature is decrypted using public key. Then the result is compared to the hash of the plain text and if they are equal it means the signature is verified.

pseudo code:

explode(input) --> plain_text , signature
if( decrypt(signature,public_key) == md5(plain_text) ) then signature is trusted

Now the real PHP code which I have tested and currently using:

function sign($cleartext,$private_key)
{
    $msg_hash = md5($cleartext);
    openssl_private_encrypt($msg_hash, $sig, $private_key);
    $signed_data = $cleartext . "----SIGNATURE:----" . $sig;
    return mysql_real_escape_string($signed_data);
}

function verify($my_signed_data,$public_key)
{
    list($plain_data,$old_sig) = explode("----SIGNATURE:----", $my_signed_data);
    openssl_public_decrypt($old_sig, $decrypted_sig, $public_key);
    $data_hash = md5($plain_data);
    if($decrypted_sig == $data_hash && strlen($data_hash)>0)
        return $plain_data;
    else
        return "ERROR -- untrusted signature";
}
like image 144
Omidoo Avatar answered Sep 24 '22 00:09

Omidoo