How to digitally sign a file in PHP

I made a user table in my database with different columns to store user information. I also added two columns public_key and private_key . When a user registers, his information will be inserted into the table. plus i use:

// 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 pass it to the user so that each user has a key pair. I want my users to be digitally signed, so when they upload a file, they sign it.

I decided to first sign the sample file (msg.txt) to find out if I can continue and then continue. He looks straight:

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

The problem is this: what are signature_cert.pem and private_key.pem? I inserted my generated public key in sign_cert.pem and private 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.

+4
php digital-signature
source share
2 answers

I came to the conclusion why not make my own digital signature function.

The digital signature algorithm works as follows: first, the plaintext is hashed, then it is encrypted with the user's secret key, and then the result is combined with the plaintext.

pseudo code:

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

To verify: the input is divided into plain text and signature. then the signature is decrypted using the public key. The result is then compared with a hash of plain text, and if they are equal, this means that 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 that I tested and am 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"; } 
+5
source share

signed_cert.pem and private_key.pem are the certificates that you use to sign this file. Therefore, if you saved them in the database, you need to dump them into files called signature_cert.pem and private_key.pem.

The error you get is that openssl is trying to download these files, and since they do not exist, it claims.

If you write these files to your hard drive from your database, plase TAKE IN MIND:

  • DO NOT store it in a publicly accessible folder (avoid the DOCUMENT_ROOT AND temp directory). Especially for a secret key to avoid security problems.
  • Remove them when you do this.

In addition, instead of having these certificates in the database, you can store them in a folder for each user to prevent the file from being written off when signing. Of course, this folder should not be accessible to anyone.

Additional Information: PHP openssl_pkc7_sign

+1
source share

All Articles