<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/faq.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'es',
  ),
  'this' => 
  array (
    0 => 'faq.passwords.php',
    1 => 'Hash de Contrase&ntilde;as',
    2 => 'Hash de contrase&ntilde;as seguro',
  ),
  'up' => 
  array (
    0 => 'faq.php',
    1 => 'FAQ',
  ),
  'prev' => 
  array (
    0 => 'faq.using.php',
    1 => 'Usar PHP',
  ),
  'next' => 
  array (
    0 => 'faq.html.php',
    1 => 'PHP y HTML',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    'path' => 'faq/passwords.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="faq.passwords" class="chapter">
 <h1 class="title">Hash de contraseñas seguro</h1>

 

 <p class="simpara">
  Esta sección explica las razones que justifican el uso de funciones hash
  para proteger las contraseñas. También se explica cómo hacerlo de un modo efectivo.
 </p>

 <div class="qandaset"><ol class="qandaset_questions"><li><a href="#faq.passwords.hashing">
    
     &iquest;Por qu&eacute; debo usar hash en las contrase&ntilde;as de los usuarios de mi aplicaci&oacute;n?
    
   </a></li><li><a href="#faq.passwords.fasthash">
    
     &iquest;Por qu&eacute; las funciones hash m&aacute;s comunes como md5 y
     sha1 no son adecuadas para las contrase&ntilde;as?
    
   </a></li><li><a href="#faq.passwords.bestpractice">
    
     &iquest;Qu&eacute; hash debo aplicar a mis contrase&ntilde;as, si las funciones hash m&aacute;s comunes
     no son adecuadas?
    
   </a></li><li><a href="#faq.passwords.salt">
    
     &iquest;Qu&eacute; es una sal (salt)?
    
   </a></li><li><a href="#faq.password.storing-salts">
    
     &iquest;C&oacute;mo almaceno mis sales?
    
   </a></li></ol></div>
  <dl class="qandaentry" id="faq.passwords.hashing">
   <dt><strong>
    <p class="simpara">
     ¿Por qué debo usar hash en las contraseñas de los usuarios de mi aplicación?
    </p>
   </strong></dt>
   <dd class="answer">
    <p class="simpara">
     El hash de contraseñas es una de las consideraciones de seguridad más elementales
     que se deben llevar a la práctica al diseñar una aplicación que acepte contraseñas
     de los usuarios. Sin hashing, cualquier contraseña que se almacene en la
     base de datos de la aplicación podrá ser robada si la base de datos se ve comprometida, con
     lo que inmediatamente no sólo estaría comprometida la aplicación, sino también
     las cuentas de otros servicios de nuestros usuarios, siempre y cuando no utilicen
     contraseñas distintas.
    </p>
    <p class="simpara">
     Si aplicamos un algoritmo hash a las contraseñas antes de almacenarlas
     en la base de datos, dificultamos al atacante el determinar la contraseña
     original, pese a que en un futuro podrá comparar el hash resultante con
     la contraseña original.
    </p>
    <p class="simpara">
     Sin embargo, es importante tener en cuenta que el hecho de aplicar hash a las contraseñas sólo
     protege de que se vean comprometidas las contraseñas almacenadas, pero no las protege
     necesariamente de ser interceptadas por un código malicioso inyectado en la
     propia aplicación.
    </p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.passwords.fasthash">
   <dt><strong>
    <p class="simpara">
     ¿Por qué las funciones hash más comunes como <span class="function"><a href="function.md5.php" class="function">md5()</a></span> y
     <span class="function"><a href="function.sha1.php" class="function">sha1()</a></span> no son adecuadas para las contraseñas?
    </p>
   </strong></dt>
   <dd class="answer">
    <p class="simpara">
     Los algoritmos hash como MD5, SHA1 o SHA256 están diseñados para
     ser muy rápidos y eficientes. Con las técnicas y equipos modernos,
     es algo trivial <q class="quote">extraer por fuerza bruta</q> la salida de estos algoritmos,
     para determinar los datos de entrada originales.
    </p>
    <p class="simpara">
     Dada la velocidad con que los ordenadores actuales pueden <q class="quote">invertir</q> estos algoritmos
     hash, muchos profesionales de la seguridad recomiendan encarecidamente no
     utilizarlas como funciones hash para contraseñas.
    </p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.passwords.bestpractice">
   <dt><strong>
    <p class="simpara">
     ¿Qué hash debo aplicar a mis contraseñas, si las funciones hash más comunes
     no son adecuadas?
    </p>
   </strong></dt>
   <dd class="answer">
    <p class="simpara">
     Al aplicar un algoritmo hash, los dos factores más importantes son
     el coste computacional y la sal. Cuanto más cueste aplicar un algoritmo
     hash, más costará analizar su salida por fuerza bruta.
    </p>
    <p class="simpara">
     PHP proporciona una
     <a href="book.password.php" class="link">API de hash de contraseñas nativa</a> que
     maneja cuidadosamente <a href="function.password-hash.php" class="link">el empleo de hash</a>
     y la <a href="function.password-verify.php" class="link">verificación de contraseñas</a>
     de una manera segura.
    </p>
    <p class="simpara">
     El algoritmo recomendado para el empleo de contraseñas con hash es Blowfish, que
     es también el predeterminado de la API de hash de contraseñas, que, aunque
     es significativamente más caro computacionalmente que MD5 o SHA1, sigue
     siendo escalable.
    </p>
    <p class="simpara">
     La función <span class="function"><a href="function.crypt.php" class="function">crypt()</a></span> también está disponible para el hash de
     contraseñas, pero solo se recomienda para la interoperabilidad con otros
     sistemas. En su lugar, se recomienda encarecidamente el uso de la
     <a href="book.password.php" class="link">API de hash de contraseñas nativa</a>
     siempre que sea posible.
    </p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.passwords.salt">
   <dt><strong>
    <p class="simpara">
     ¿Qué es una sal (salt)?
    </p>
   </strong></dt>
   <dd class="answer">
    <p class="simpara">
     Una sal criptográfica es un dato que se utiliza durante el proceso de hash
     para eliminar la posibilidad de que el resultado pueda buscarse a partir de
     una lista de pares precalculados de hash y sus entradas originales, conocidas
     como tablas rainbow.
    </p>
    <p class="simpara">
     Es decir, una sal es un pequeño dato añadido que hace que los hash
     sean significantemente más difíciles de crackear. Existe un gran número de
     servicios online que ofrecen grandes listas de códigos hash precalculados,
     junto con sus datos de entrada originales. El uso de una sal hace muy difícil o
     imposible encontrar el hash resultante en cualquiera de estas listas.
    </p>
    <p class="simpara">
     <span class="function"><a href="function.password-hash.php" class="function">password_hash()</a></span> creará una sal aleatoria si no se
     proporciona una, siendo esta generalmente la estrategia más sencilla y
     segura.
    </p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.password.storing-salts">
   <dt><strong>
    <p class="simpara">
     ¿Cómo almaceno mis sales?
    </p>
   </strong></dt>
   <dd class="answer">
    <p class="simpara">
     Al utilizar <span class="function"><a href="function.password-hash.php" class="function">password_hash()</a></span> o
     <span class="function"><a href="function.crypt.php" class="function">crypt()</a></span>, el valor devuelto incluye la sal como parte
     del hash generado. Este valor debería almacenarse tal cual en la
     base de datos, ya que incluye información sobre la función hash que se
     empleó y así proporcionarla directamente a
     <span class="function"><a href="function.password-verify.php" class="function">password_verify()</a></span> al
     verificar contraseñas.
    </p>
    <div class="warning"><strong class="warning">Advertencia</strong>
     <p class="simpara">
      Siempre debería utilizarse <span class="function"><a href="function.password-verify.php" class="function">password_verify()</a></span> en lugar de
      volver a aplicar hash y comparar el resultado con un hash almacenado, a fin de
      evitar ataques de temporización.
     </p>
    </div>
    <p class="simpara">
     El siguiente diagrama muestra el formato de un valor devuelto por
     <span class="function"><a href="function.crypt.php" class="function">crypt()</a></span> o <span class="function"><a href="function.password-hash.php" class="function">password_hash()</a></span>. Como se
     puede observar, son autocontenidos, con toda la información del
     algoritmo y la sal requerida para futuras verificaciones de contraseñas.
    </p>
    <p class="para">
     <div class="mediaobject">
      
      <div class="imageobject">
       <img src="images/2a34c7f2e658f6ae74f3869f2aa5886f-crypt-text-rendered.svg" alt="
       Los componentes del valor devuelto por password_hash y crypt: en
       orden, el algoritmo elegido, las opciones del algoritmo, la sal utilizada,
       y la contraseña con hash.
      " width="690" height="192" />
      </div>
     </div>
    </p>
   </dd>
  </dl>
 

</div>
<?php manual_footer($setup); ?>