{"id":1293,"date":"2015-03-06T12:14:10","date_gmt":"2015-03-06T18:14:10","guid":{"rendered":"https:\/\/www.lastdragon.net\/?p=1293"},"modified":"2015-03-07T12:17:47","modified_gmt":"2015-03-07T18:17:47","slug":"cifrar-archivo-asimetricamente-con-php","status":"publish","type":"post","link":"https:\/\/www.lastdragon.net\/?p=1293","title":{"rendered":"Cifrar archivo asimetricamente con PHP"},"content":{"rendered":"<p>En este articulo dejare el c\u00f3digo para cifrar archivos con PHP usando el API de OPENSSL Asim\u00e9tricamente ( RSA )<\/p>\n<p><strong>Hay 2 formas de cifrar las cosas, cifrados asim\u00e9tricos y sim\u00e9trico.<\/strong><\/p>\n<p>Un cifrado sim\u00e9trico es el que tiene una llave activada con un password \u00fanico que deben conocer qui\u00e9nes van a manipular esa informaci\u00f3n, la iron\u00eda de esto radica en que si son personas que est\u00e1n en lugares remotos enviar el password en primer lugar ya es un desprop\u00f3sito, un atacante snifeando la conexi\u00f3n puede capturar el passowrd, luego capturar los datos cifrados y usar el password para descifrarlos. <\/p>\n<p>Un cifrado asim\u00e9trico es con claves p\u00fablicas  y privadas, actualmente no hay forma de atacar excepto con fuerza bruta  ( a maquinazos )  siempre y cuando la cantidad de bits en la llaves de cifrado sea lo suficientemente alto permanece seguro, en el 2015 es inviable intentar atacar una llave de 2048 bits y ya ni hablar de 4096 bits, mientras m\u00e1s poder de c\u00e1lculo\/computo se tenga m\u00e1s larga puede ser la llave sin afectar el rendimiento<\/p>\n<p><strong>Asim\u00e9trico vs Sim\u00e9trico<\/strong><\/p>\n<p>Un cifrado sim\u00e9trico es muy seguro y r\u00e1pido, su rapidez tambi\u00e9n es su perdici\u00f3n, actualmente con el poder de c\u00f3mputo actual es casi imposible romper un AES pero en el futuro esto ser\u00e1 posible porque su llave tiene un limite fijo<\/p>\n<p>Un cifrado asim\u00e9trico tiene el mismo limitante, excepto que la longitud de la lleve puede ir al infinito, mientras m\u00e1s grande es la llave m\u00e1s seguro es, cuando aumente el poder de computo para darle un maquinazo lo \u00fanico  que habr\u00eda que hacer es usar una llave con longitud m\u00e1s alta. Se debe considerar que al ser un sistema m\u00e1s complicado. Cifrar o descifrar cosas con un m\u00e9todo asim\u00e9trico se vuelve lento y al CPU se le tortura con pesadas cargas de procesamiento.<\/p>\n<p>Simplemente es una por otra, quieres velocidad de cifrado usas un m\u00e9todo sim\u00e9trico aunque es m\u00e1s vulnerable, quieres extrema seguridad usa asim\u00e9trico pero si tienes que cifrar y descifrar constantemente tus procesos entraras en un cuello de botella.<\/p>\n<p><strong>Lo mejor de los 2 mundos.<\/strong><\/p>\n<p>Actualmente lo que se hace es usar ambos m\u00e9todos en una misma conexi\u00f3n, si el problema del m\u00e9todo sim\u00e9trico es enviar una clave para que el receptor descifre los datos. Lo que se hace es establecer la conexi\u00f3n asim\u00e9trica y una vez asegurada la conexi\u00f3n se env\u00eda en ese momento la clave se deja de usar asim\u00e9tricamente y se pasa a sim\u00e9trico.<\/p>\n<p><strong>Entendiendo el concepto de transporte seg\u00fan la llave y la longitud de la llave.<\/strong><\/p>\n<p>Muchas veces se habla de llaves de 1024 bits o de 128 bytes indistintamente, es porque son lo mismo.<\/p>\n<p>Un byte son exactamente 8 bits, 128 bytes contienen exactamente 1024 bits ( 128 x 8 ) = 1024<\/p>\n<p>Un bloque de informaci\u00f3n asim\u00e9trica con llave 1024 puede transportar un m\u00e1ximo de 128 bytes, por supuesto que no todos esos bytes son usados para el transporte de informaci\u00f3n, se requieren 11 bytes para el manejo de los datos cifrados dejando un total disponible de 117 bytes por cada bloque para ser usados por el programador o la aplicaci\u00f3n y cifrar las cosas.<\/p>\n<p>1024 bits = 128 bytes, de los cuales ( 128 bytes \u2013 11 bytes ) = 117 \u00fatiles<br \/>\n2048 bits = 256 bytes de los cuales ( 256 bytes \u2013 11 ) = 245 bytes \u00fatiles<br \/>\n4096 bits = 512 bytes , etc, etc<\/p>\n<p><strong>Asumiendo que trabajamos con una llave de 1024 bits<\/strong><\/p>\n<p>El bloque siempre tendr\u00e1 un tama\u00f1o de 128 bytes aunque solo cifres la palabra <em>hola<\/em>, tambi\u00e9n hay que tomar en cuenta que si cada bloque es de un m\u00e1ximo de 117 bytes el archivo a cifrar se tiene que dividir en peque\u00f1os bloques de 117 bytes cada uno de estos bloques tendr\u00e1 que ser cifrado individualmente para finalmente concatenar los bloques en un \u00fanico archivo cifrado al 100%. Otra cosa a considerar es que el archivo cifrado aumentara considerablemente de tama\u00f1o debido a que cada 117 bytes reales del archivo se le suma los 11 bytes del algoritmo de cifrado.<\/p>\n<p>Para descifrar el archivo se hace lo mismo pero la inversa, esta vez se toman los 128 bytes del bloque y se descifran dando por resultado los 117 bytes originales, que deber\u00e1n ser concatenados en un \u00fanico archivo descifrado dando por resultado el archivo original.<\/p>\n<p>Ejemplo con PHP<\/p>\n<p><strong>Cifrar un archivo subido mediante formulario WEB<\/strong><\/p>\n<p><code>&lt;?php<\/p>\n<p>function ssl_encrypt($source,$type,$key){<\/p>\n<p>$maxlength=245;<br \/>\n$output='';<br \/>\nwhile($source){<br \/>\n&nbsp; $input= substr($source,0,$maxlength);<br \/>\n&nbsp; $source=substr($source,$maxlength);<br \/>\n&nbsp; if($type=='private'){<br \/>\n&nbsp;&nbsp;&nbsp; $ok= openssl_private_encrypt($input,$encrypted,$key);<br \/>\n&nbsp; }else{<br \/>\n&nbsp;&nbsp;&nbsp; $ok= openssl_public_encrypt($input,$encrypted,$key);<br \/>\n&nbsp; }<\/p>\n<p>&nbsp; $output.=$encrypted;<br \/>\n}<br \/>\nreturn $output;<br \/>\n}<\/p>\n<p>$uploads_dir = \"\/tmp\";<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $tmp_name =<br \/>\n$_FILES[\"userfile\"][\"tmp_name\"][0];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $name1 =<br \/>\n$_FILES[\"userfile\"][\"name\"][0];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br \/>\nmove_uploaded_file($tmp_name, \"$uploads_dir\/$name1\");<\/p>\n<p>\n$archivo1 = $uploads_dir.\"\/\".$name1;<\/p>\n<p>$gestor = fopen($archivo1, \"r\");<br \/>\n$dato = fread($gestor, filesize($archivo1));<br \/>\nfclose($gestor);<\/p>\n<p>unlink ($archivo1);<\/p>\n<p>header(\"Content-Type: application\/octet-stream\");<br \/>\nheader(\"Content-Disposition: attachment; filename=\\\"$name1.rsa\\\"\");<\/p>\n<p>echo ssl_encrypt($dato,\"publica\",\"file:\/\/publica.key\");<\/p>\n<p>?&gt;<\/p>\n<p><\/code><\/p>\n<p><strong>Descifrado de un archivo subido mediante formulario WEB<\/strong><\/p>\n<p><code>&lt;?php<\/p>\n<p>function ssl_decrypt($source,$type,$key){<\/p>\n<p>$maxlength=256;<br \/>\n$output='';<br \/>\nwhile($source){<br \/>\n&nbsp; $input= substr($source,0,$maxlength);<br \/>\n&nbsp; $source=substr($source,$maxlength);<br \/>\n&nbsp; if($type=='private'){<br \/>\n&nbsp;&nbsp;&nbsp; $ok= openssl_private_decrypt($input,$out,$key);<br \/>\n&nbsp; }else{<br \/>\n&nbsp;&nbsp;&nbsp; $ok= openssl_public_decrypt($input,$out,$key);<br \/>\n&nbsp; }<\/p>\n<p>&nbsp; $output.=$out;<br \/>\n}<br \/>\nreturn $output;<\/p>\n<p>}<\/p>\n<p>$uploads_dir = \"\/tmp\";<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $tmp_name =<br \/>\n$_FILES[\"userfile\"][\"tmp_name\"][0];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $name1 =<br \/>\n$_FILES[\"userfile\"][\"name\"][0];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br \/>\nmove_uploaded_file($tmp_name, \"$uploads_dir\/$name1\");<\/p>\n<p>\n$archivo1 = $uploads_dir.\"\/\".$name1;<\/p>\n<p>$gestor = fopen($archivo1, \"r\");<br \/>\n$dato = fread($gestor, filesize($archivo1));<br \/>\nfclose($gestor);<\/p>\n<p>unlink ($archivo1);<\/p>\n<p>$nombrearchivo = substr($name1, 0, -4);<\/p>\n<p>header(\"Content-Type: application\/octet-stream\");<br \/>\nheader(\"Content-Disposition: attachment; filename=\\\"$nombrearchivo\\\"\");<\/p>\n<p>echo ssl_decrypt($dato,\"private\",\"file:\/\/privada.key\");<\/p>\n<p>?&gt;<br \/><\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En este articulo dejare el c\u00f3digo para cifrar archivos con PHP usando el API de OPENSSL Asim\u00e9tricamente ( RSA ) Hay 2 formas de cifrar las cosas, cifrados asim\u00e9tricos y sim\u00e9trico. Un cifrado sim\u00e9trico es el que tiene una llave activada con un password \u00fanico que deben conocer qui\u00e9nes van a manipular esa informaci\u00f3n, la&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1293","post","type-post","status-publish","format-standard","hentry","category-programacion"],"_links":{"self":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts\/1293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1293"}],"version-history":[{"count":3,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts\/1293\/revisions"}],"predecessor-version":[{"id":1296,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=\/wp\/v2\/posts\/1293\/revisions\/1296"}],"wp:attachment":[{"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lastdragon.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}