openssl_pkcs7_encrypt

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

openssl_pkcs7_encryptEncriptar un mensaje S/MIME

Descripción

bool openssl_pkcs7_encrypt ( string $infile , string $outfile , mixed $recipcerts , array $headers [, int $flags = 0 [, int $cipherid = OPENSSL_CIPHER_RC2_40 ]] )

openssl_pkcs7_encrypt() toma el contenido del archivo nombrado por infile y lo encripta usando un cifrado RC2 de 40 bits por lo que sólo lo podrá leer los destinatarios previstos especificados por recipcerts.

Parámetros

infile

outfile

recipcerts

Un único certificado X.509, o una matriz de certificados X.509.

headers

headers es una matriz de cabeceras que serán añadidas delante de la información después de que haya sido encriptada.

headers puede ser una matriz asociativa con las claves como el nombre de la cabecera, o una matriz indexada, donde cada elemento contiene una sola línea de cabecera.

flags

flags se puede usar para especificar las opciones que afectan al proceso de codificación - véase constantes PKCS7.

cipherid

Una de las constants de cipher.

Valores devueltos

Devuelve TRUE en caso de éxito o FALSE en caso de error.

Ejemplos

Ejemplo #1 Ejemplo de openssl_pkcs7_encrypt()

<?php
// el mensaje que quiere encriptar y enviar a su agente secreto
// en el campo, conocido como nighthawk. Tiene su certificado
// en el archivo nighthawk.pem
$data = <<<EOD
Nighthawk,

Alto secreto, ¡Confidencial!

¡El enemigo nos está rodeando! ¡Encuéntrese conmigo en el café a las 8.30am
para obtener su pasaporte falso!

C.G.
EOD;

// cargar la clave
$clave file_get_contents("nighthawk.pem");

// guardar el mensaje en un archivo
$fp fopen("mensaje.txt""w");
fwrite($fp$data);
fclose($fp);

// encriptarlo
if (openssl_pkcs7_encrypt("mensaje.txt""enc.txt"$clave,
    array(
"Para" => "nighthawk@example.com"// sintaxis asociativa
          
"De: C.G. <cg@example.com>"// sintaxis indexada
          
"Tema" => "Confidencial"))) {
    
// mensaje firmado - ¡envíelo!
    
exec(ini_get("ruta_correo") . " < enc.txt");
}
?>

add a note add a note

User Contributed Notes 14 notes

up
2
koen dot thomeer at pubmed dot be
9 years ago
In the previous example, the decrypted message couldn't be read by the 'popular' mail clients. Those mail clients needed also headers in the encrypted part.

I also noticed that there were some double headers in the previous example ('To:' and 'Subject:' were not overriden by the Headers parameter in mail()). This is also corrected by unsetting 'To:' and 'Subject:' in $headers_msg.

body.txt is the file with the mail body.
publickey.cer is the file with the public certificate.

<?php
// Setup mail headers.
$headers = array("From" => "from@mail.com", "To" => "to@mail.com", "Subject" => "Encrypted mail readable with most clients", "X-Mailer" => "PHP/".phpversion());

// Get the public key certificate.
$pubkey = file_get_contents("publickey.cer");

// Header for encrypted part
$eol = "\r\n";
$enc_header .= "From: ".$headers['From'].$eol;
$enc_header .= "To: ".$headers['To'].$eol;
$enc_header .= "Subject: ".$headers['Subject'].$eol;
$enc_header .= "Content-Type: text/plain; format=flowed; charset=\"iso-8859-1\"; reply-type=original".$eol;
$enc_header .= "Content-Transfer-Encoding: 7bit".$eol;
$enc_header .= "\n";

// Prepend header for encrypted message
$body = file_get_contents("body.txt");
$msg = $enc_header.$body;
file_put_contents("msg.txt", $msg);

// Remove some double headers for mail()
$headers_msg = $headers;
unset(
$headers_msg['To'], $headers_msg['Subject']);

// Encrypt message
openssl_pkcs7_encrypt("msg.txt", "enc.txt",$pubkey,$headers_msg,0,1);

// Seperate headers and body for mail()
$data = file_get_contents("enc.txt");
$parts = explode("\n\n", $data, 2);

// send mail
mail($headers['To'], $headers['Subject'], $parts[1], $parts[0]);
?>
up
2
Anonymous
5 years ago
To build on what people have already done, below is a function that takes a from address, an array of e-mails/public keys, a subject, and a message and sends out an encrypted message using the appropriate public key.

Since we're sending an encrypted message, the assumption is that what we're sending is actually critical. As a result the files used for sending the message are immediately shredded.

$recipients = Array("user@example.com"=>file_get_contents("cert.pem"));
$body = 'secret text';
   sendSignedMail("me@examplel.com", $recipients, "Test Message", $body);

  //Recepients is an array of e-mail address=>Key
  function sendSignedMail($from, $recepients, $subject, $body){
    foreach($recepients AS $email=>$key){
      $tfn_in = tempnam("/tmp", "b");
      $tfn_out = tempnam("/tmp", "e");

      $handle = fopen($tfn_in, "w");
      fwrite($handle, $body);
      fclose($handle);
   
      openssl_pkcs7_encrypt($tfn_in, $tfn_out, $key,
          array("To" => $email,
                "From" => $from,
                "Subject" => $subject), 0);
      $data = file_get_contents($tfn_out);
     
      //Shred the files since this is sensitive data.
      $handle = popen("/usr/bin/shred -n 3 -u $tfn_in", 'r');
      pclose($handle);
      $handle = popen("/usr/bin/shred -n 3 -u $tfn_out", 'r');
      pclose($handle);
     
     
      $parts = explode("\n\n", $data, 2);//Fixes headers in mail function

      mail($email, $subject, $parts[1], $parts[0]);
 
    }
 
  }
up
2
ungdi at hotmail dot com
12 years ago
Amongst the many discussions about signing or encrypting email by itself, none really discuss the pain of having an email BOTH signed AND encrypted.

*** What do you do first? Sign then Encrypt? Or Encrypt then Sign?

According to RFC 2311, you can encrypt then sign or sign then encrypt. However, it depends on the client in which you are programming for. In my experience, in Outlook 2000, it prefers it Encrypt then Sign. While in Outlook 2003, it is Sign then Encrypt. Generally, you want Sign then Encrypt, as it seems most logical from a snail-mail piece point of view. You first sign a letter than put it in an envelope. Certain clients complain if you do it in an order it does not like, so you may want to experiement with it.

*** Example of doing both signing AND encrypting.

When you perform the first function, do NOT put in any headers in the headers array parameters, you want to put it in the SECOND function you want to perform. If you put the headers in the first function, the second function will hide it from the mail servers. You do not want that. Here I will sign then encrypt.

<?
// Setup mail headers.
$headers = array("To" => "someone@nowhere.net",
    
"From" => "noone@somewhere.net",
    
"Subject" => "A signed and encrypted message.");

// Sign the message first
openssl_pkcs7_sign("msg.txt","signed.txt",
    
"signing_cert.pem",array("private_key.pem",
    
"password"),array());

// Get the public key certificate.
$pubkey = file_get_contents("cert.pem");

//encrypt the message, now put in the headers.
openssl_pkcs7_encrypt("signed.txt", "enc.txt",
    
$pubkey,$headers,0,1);

$data = file_get_contents("enc.txt");

// separate header and body, to use with mail function
//  unfortunate but required, else we have two sets of headers
//  and the email client doesn't decode the attachment
$parts = explode("\n\n", $data, 2);

// send mail (headers in the Headers parameter will override those
//  generated for the To & Subject parameters)
mail($mail, $subject, $parts[1], $parts[0]);
?>

Note that if you use a function that picks up the data from the disk to be used in another function in your program, remember that you may have used the explode("\n\n",$data,2) function which may have removed the spacing between the header and the message content.

When you take the signed message and feed it in to the encryption part, you have to remember that the line spacing must also be fed AS PART OF THE MESSAGE BODY! If you plan to sign then encrypt, do not feed the header output from the signing into the encrypting as part of the headers array parameter! The output of the signing should stay as part of the message body being encrypted. (And the same is true if you are doing the reverse of encrypting then signing.) An example of both the signing and encryption function made in to a routine for reusability, and then called to sign and encrypt a message.

*** Example of signing and encrypting executed from a routine function for code reusability through a program.

THIS IS WRONG!:
<?
// [0] of Array contains headers of message. [1] of Array contains signed body of message.
$signedOutputArray = signMessage($inpano>op b">$data, 2);

// send mail (headers in the Headers parameter will override those
//  generated fr />
$signedthe encry reusabifault">mutputArray // Sign "keyword">= signMessage
($inpano>op b">$data">// Sian>, 2$parts[,$headers$parts$mail, $subject;
// send mass="keyword">[signMessage$parts
[,$headers$parts reusabifault">mutputArray = signMessage($inpano>op b">$data, 2);

$pubkey $signedOfault">mutputArray // Sign lass="keen called to signing must also be cl="default">ncry reusabifault"an class="default">signMessage
(
$headers// Sian>, 2$parts// Prepend headerge ord">;

$headers$parts[// send mail (headers in the Headers parameter will override those
//  class="keyword">,
$subject;
// send mass="keyword">[signMessage$parts
[,$headers$parts
up
up
y" id="V51006" title="100% like this..."> 2
ungdi a1 hotmail dot com<1matqo1lassazet titlsk2005-03-16 03:19">12 years ago Amongst the many discussions about9654789v or encrypting email by itself, none really disFd ANveryWhatwho splasslokeen ctimserryhe cliene functmtheirse /altis.a');<:ill override1.)classt.$he>("body.txt");
$msg = $enc_header.;
file_put_contents("msg.txt", $msg);

= $enc_header= e c- and enryword">= = ng the >e , check and encrypte.com"=&pan>s">
up
up
y" id="V107892" title="100% like this..."> 2
ungdi a0us5 years ago19071892
To build on what people have alrea1907189; below is a function that takes a from address, and nd the><_inw="#51(assleasctaubNOT4.2.0)olor: #the s509, o unars_msg.
dded.$bodylt">ncrybase64 u.<>SSLerrissof headet? Sigerfasnspan>dded.$pan><pn kclas:oeaders.
$headersmu want thaeld, kn fasnnighthawk.pemmu want thathe: #FF8000">//"default">$headers($headers);

//  class="kTopyage", rd">);

= those
//  class="k enryeyes anlyrd">);

//  class="kTay asemy /s &nbs shoulrd">);

//  class="kMeeord" n encrycaf" n epan>=gn class/>);

//  class="kHQ cll ovp;¡span class="keyword">(
cll override those
// pan>$headersspan class="keyword">("cert.pem", $data);

ord">, $msg"password"$headersfpn class="keyword">("body.txt"$msg);

= $headers$subject);

$headers$subject cll override those
// pan>$headers$subject
, "enc.txt",$pubkey,,"someone@nowhere.net",
    
// sintaxis a>$headers$headers, // Sign -sendiiit!nction

&nbclass$enc_header$subject
"enc.txt"// Prepend head &nbs te header and body, to use with mail function<} default">$headerscaders]s">
up
up
y" id="V107892" title="100% like this..."> 2
5 years ago To build on what people have already34789v or encrypting email by itself, none really disAf not inkerm.class="ksthd spn k>s">
up
up
y" id="V51006" title="100% like this..."> 2
12 years ago54976&a
Amongst the many discussions about 54976&vsage couldn't be read by the 'popular' mail clie 'so>
up
up
y" id="V51006" title="100% like this..."> 2
12 years ago <11:0pcode"> Amongst the many discussions about446696&v or encrypting email by itself, none really disAubNOTPHP 5.0.0! If you plae sab>ng tOR 128yde iRC2 ng mment">// [0] e snewlass="defadescrin>ng t doing n abeains heboolft"s">
up
up
y" id="V51006" title="100% like this..."> 2
12 years ago Amongst the many discussions about365986&v or encrypting email by itself, none really disU assuendilassom aworvery />//  a />Whenpan>//  a fromen c $tfn />&nbsn 3 -uit'sbeys, a st.Whenten><' in>// Sign) ge oignorcomment/spa(base64 // Sign t// [0] e ssolu>ng the quitry rients decfrof okrd" nl="t892owhpan lier">ekospaitD encI'mnshand hncrybdefa Ter tlass $ody being esnspan>ddi>ng al_hameters)
// [0]Y yopan><>eed fromp09,ft:' intword">(// Sign n>$hea">$he>n>("cert.pem");

//encrypt the message, now put in the headers.
, "enc.txt",$pubkey,,"someone@nowhere.net",
    
// sintaxis a>$headers,
    
// ssp;sintaxis i>$headers, ("enc.txt");

// separate header and body, to use with mail function
//  unfortunate but required, else we have two sets of headers
//  and the email client doesn't decode the attachment
$parts = explode("\n\n","someone@noss="keyword">($inpano>op b">$data, 2);

// send mail (headers in the Headers parameter will override thword">("\n\n", $subject, $parts[1], ,$headers
E178/spown!" class="us36598oteu">up up up
y" id="V5178/s9title="100% like this..."> 2 ungdi a0us12 years ago54976&a
<t">&lF">);,d="Hcom1"defaul36598ounate butcahidy in>);// blankd fee/ n><t">&lFan S/MIME, t thathD epl(sjeehe of t (includbr />//&nbs)unatefurfnr n>);
n claso"ibsnthe sn ""S/MIME
// blankd fee/ pan>// the Headerslankd fee/ pan><t">&ln />//&pular' put it in twhe disk >)se we haapp>ar; a />Whenpan>
34789thand . (Andy being efinto use wis="key34789 a rout thatb0codeat>Whentrel(sj .las it rror; a />WhWh> S/MIME
);d="Hcom,yettfoun updded.$pan>&t;pn kclas:oeaders.
$headers]);n ECOND feelm addresrlankdeen ampav vidbr /' put it in siwo setshe il b15s=one o notof">ncn class;   fasnnighthlasssnthe sn ""lt">mu wa, class (/>Wheeyword">(headero nord">)! class (/>Whent, rd">);

! rd">);

//  cla! class (/>WhHQbsp; clas;bsnthe sn ""sof);
class;bje = > cll o("",n cln(efault"> class="defaultspan> ord">, class;fpt = tempn message,p", "e");
    ($tfn_in, $tfn_ou"se<@sennody = 'e.net"
$headers
&nb";sintaxis a>
&nbault">$headers
 an class="d))lass="k$body){
contents(ients"
$headern cl(sppan><(ass$enc_header<u you s. Myt requirWhHtrel(sjptinunspd="Hcom11, yobeinger,om aayl="t892owhcenhm>u you sbout9654789v "someone@noss="keyword">( headet? Sigerfasnspan>dded.$pan>&t;pn kclas:oeaders.
$headers]);n rlankd fees="defa><-typss="keywspan><>, <-typs:90718/ss="; mu wantax/b/spa,ass="sntaxi1/spaeeyword">(headero nord">)!ntax/i1/spaass="sntaxp/spaent, rd">);

! rd">);

//  cla!ntax/p/spaass="sntaxp/spaHQntax/p/spaass="sntax/is="/span>"someone@noss="keyword">();
classspan>"enc.tx />//  class="kHQ cll ovp;¡span class="keyword">( cll override those
// pan>$headersspan class="keyword">("cert.pem", >nction

  &nban;bsnthe sn ""tring">"someone@noss="keyword">(
wnguniquy iem claryn clncramrdea,t decfe claspan clascl>ar;07189vir 92on>, <>//  class="kHQ cll ovp;¡span class="keyword">("cert.pem", ("m requ$subject(span>"body.txt", <>//  class="kHQ cll ovp;¡span class="keyword">(ard">, <>//  class="kHQ cll ovppan class="default">$subject(span>"body.txt"ard">, <>//  class="kHQ cll ovpp;¡span class="keywordubject(span>"body.txt""password"ard">, now put in the headers.
"body.txt""body.txt"g);

= $headers"body.txt"gect);
"someone@noss="keyword">();
ault">$subject
cll override those
// pan>ard">, now put in the headers.
pan class="string">"body.txt",eader
=
t",$pubkey,nnody =eader= $headers,
    
// sintaxis a>$headers,
nbsp;sintaxis i>nction

  &nban ass="k$body){
contentppan>nction$header/span>$paclass="keyw)))nction<{nction

&nbclass$enc_header// Sign -sendiiit!nction

&nbclass$enc_header$subject
"body.txt",eader);
"ypan>nction"body.txt"un feant thathe: #FF8000">//"defaul
// pan>ard">, now put in the headers.
"body.txt"un feant thathe: #FF8000">//"defaul
// pan>,eader$headers
21823spown!" class="us36598oteu">up up up
y" id="V21823s9title="100% like this..."> 2 ¶ref="#51006"> ¶12 years ago*** Ex [0]s help clger, r /> ord"gil b08:1ptinud7 sigunsp />/twng omm* E />= WhIn]IEnsee thoTools -lass$InAmonee na$tfnr,. (And/>Wh>Cnpan><$headers$headersdded.$pan requierfa;KX-Psnspaclaan ke="keyworalreadf you but"n c, mhebrroun cX.509 (.CER)#51(assleasctaubTpan clncunisbv icedil bc"htmesa
Entt/spown!" class="us36598oteu">up /
up
/
y" id="V51006""us3/s9title="100% like this..."> 2 12 years ago54976&a
A thesn(sey,iheaRC2/40=o( y="keyw) .waysjrecrypnd . (A go<_892"> ralan> 92oseS mpl /> 92os,892"> .cde>see tho>WhIpan>chave used>submo( ppan>ch ass="daapp>arsan /sfoun ml">/>=sobl// sa> wa,dfjutse funisbrhtmil bynpanett />o Ter tlass $odR>
E220/spown!" class="us36598oteu">up up y" id="V51006""220/s9title="100% lthis..."> 2 12 years ago54976&a 210or" own!" class="us36598oteu">up up y" id="V51006"210or"9title="100% like this..."> 2 ¶ref="#51006"> ¶5 years ago19071892
To build on what people have alrea1907189; below is a function that takes a from address, and nd the><_inw="#51(assleasctaubNOT4.2.0)olor: #the s509, o unars_msg.
dded.$bodylt">ncrybase64 "ypan>nction< headet? Sigerfasnspan>dded.$pan>& t;pn kclas:oeaders.
$headers< t;pn kclas:oeaderslncrypting thll pan>"d">, "ubjectmu wa, 4789v 4789v eeyword">(headero nord">)! 4789v 4789v ent, rd">);

! rd">);

//  cla! 4789v 4789v HQ pan>"""someone@noss="keyword">();
pan>"d">, //  class="kHQ cll ovp;¡span class="keyword">( cll override those
// pan>$headersspan class="keyword">("cert.pem", >nction

  &nban; 4789v 4789v "someone@noss="keyword">(n> ord">, pan>"d">, "password"$headersfpn class="keyword">("body.txt"< pan>"d">, );

= $headers"d">, );
"someone@noss="keyword">(""$subject cll override those
// pan>$headers$subject
, "enc.txt", < ault">$headers$pubkey,,"someone@nowhere.net"$headers     // sintaxis a>$headers     /nbsp;sintaxis i>nction

  &nban ault">{ ault">$headersnction$headers$paclass="keyw)))nction<{nction

&nbclass$enc_header// Sign -sendiiit!nction

&nbclass$enc_header$subject
(} pan>"d">, // Prepend head &nbs te header and body, to use with mail function<} default">$headers .nees36598otes/id="Vu107892"> sp img src='/im eps/penssladd@2x.png') .A='add, rdens': #dth='12' het">m='12'>e t che>add, rdenss>> id="V/dy in>>