Jekyll2021-03-20T12:36:39+00:00http://jesusmg.org/feed.xmlJesús MarínCiberseguridad, y tecnología en general.
Primeras impresiones con Rust2020-06-06T00:00:00+00:002020-06-06T00:00:00+00:00http://jesusmg.org/primeras-impresiones-Rust<p>Hace tiempo venía escuchando maravillas sobre <a href="https://www.rust-lang.org/">Rust</a>, un nuevo lenguaje de bajo nivel enfocado no solo en el rendimiento, sino también en hacer software confiable. Fue esto último lo que despertó mi interés, ya que no me entraba en la cabeza como Rust podría dar lugar a aplicaciones más fiables que los lenguajes de más alto nivel, evitando problemas habituales como desbordamientos de pila, punteros nulos….</p>
<p>Así que empecé investigando un poco, y rápidamente acabé leyendo el libro <em>The Rust Programming Language</em>. Es el libro de introducción a Rust por excelencia, y se encuentra <a href="https://doc.rust-lang.org/book/title-page.html">disponible online de forma gratuita</a>.</p>
<p>Tras haberlo terminado y dedicar unas pocas horas de programación con Rust, debo decir que me ha sorprendido gratamente. Efectivamente tiene un rendimiento muy bueno, lo que me ha resultado ideal para desarrollar algunos <strong>MICRO</strong>servicios. A modo de ejemplo, <a href="https://github.com/jesmg/rust-caesar-api">he publicado en GitHub</a> un microservicio que expone dos APIs REST para realizar cifrado/descifrado Cesar.</p>
<p>Rust introduce dos conceptos que pueden ser complejos de entender al principio, pero sin embargo resultan muy útiles: propiedad y tiempos de vida. Estas dos funcionalidades permiten asegurarse, en tiempo de compilación, de que las variables y las referencias a variables se utilizan de forma adecuada. Así se evitan problemas asociados a los lenguajes de este tipo, como pueden ser referencias nulas, leaks de memoria, escrituras concurrente en una misma posición de memoria….</p>
<p>El uso correcto de variables y referencias no es lo único que comprobará el compilador, señalando otras malas prácticas y obligando a su corrección para poder llegar a ejecutar el código. Es gracias a esta funcionalidad que podemos darnos cuenta de distintos errores en cuanto los introducimos.</p>
<p>Así mismo, Rust tiene un <a href="https://rust-lang-nursery.github.io/wg-verification/">equipo de trabajo</a> cuyo objetivo es verificar con métodos formales la implementación del lenguaje, asegurando su máxima fiabilidad.</p>
<p>En conclusión, me quedo con una sensación muy buena de Rust, habiéndose ganado espacio como uno de mis lenguajes predilectos.</p>Hace tiempo venía escuchando maravillas sobre Rust, un nuevo lenguaje de bajo nivel enfocado no solo en el rendimiento, sino también en hacer software confiable. Fue esto último lo que despertó mi interés, ya que no me entraba en la cabeza como Rust podría dar lugar a aplicaciones más fiables que los lenguajes de más alto nivel, evitando problemas habituales como desbordamientos de pila, punteros nulos….Flatpakeando el TLA+ Toolbox2020-05-27T00:00:00+00:002020-05-27T00:00:00+00:00http://jesusmg.org/TLAplus-toolbox-en-flatpak<p>En las últimas entradas he hablado sobre el lenguaje (o mejor dicho, la pila de herramientas) de verificación formal TLA+. Se trata de una tecnología que, si bien aún no ha sido ampliamente adoptada, merece la pena apostar por ella dados sus <a href="https://www.hillelwayne.com/post/augmenting-agile/">grandes beneficios</a>.</p>
<p>Hace unas semanas aporté mi grano de arena a favor de la adopción de TLA+, creando un paquete de Flatpak con las herramientas principales (el llamado TLA+ Toolbox).</p>
<p>¿Por qué Flatpak?</p>
<p>Hasta hace poco las opciones de instalación del TLA+ Toolbox eran las más clásicas: Descargar el .rpm o .dev del <a href="https://github.com/tlaplus/tlaplus/releases">repositorio oficial</a>, o directamente los binarios y archivos necesarios para la ejecución.</p>
<p>Flatpak es un sistema de paquetería independiente de la distribución utilizada, fácil de usar, y quizás lo más importante: <a href="https://flatpak.org/faq/">ejecuta la aplicación en un sandbox</a> con todas sus dependencias. El tamaño de las instalaciones aumentará, a cambio de las ventajas derivadas de que la aplicación se ejecute en un entorno con las condiciones que los desarrolladores determinen.</p>
<p>Preparar el paquete no ha sido complicado, y ya <a href="https://flathub.org/apps/details/org.lamport.tla.toolbox">se encuentra disponible en el store oficial de Flatpak</a>.</p>
<p>La aplicación se distribuye bajo un entorno Freedesktop. Actualmente descarga las releases del repositorio oficial y simplemente las instala. Esto no es la mejor práctica a la hora de empaquetar aplicaciones en Flatpak, siempre que pueda evitarse. Aún hay trabajo futuro y el repositorio se encuentra abierto a contribuciones.</p>
<p>Las principales tareas a abordar son:</p>
<ul>
<li>Construir el paquete de TLA+ Toolbox a partir del código fuente, y no de una release.</li>
<li>Instalar un backend para TLAPS (TLA+ Proof System).</li>
<li>Instalación de la aplicación pdflatex en el paquete, para poder exportar especificaciones escritas en TLA+ a documentos PDF. Quizás podría hacerse instalando todo el entorno de <a href="https://github.com/flathub/org.freedesktop.Sdk.Extension.texlive">texlive</a>, pero esto incrementaría enormemente el peso del paquete final.</li>
</ul>En las últimas entradas he hablado sobre el lenguaje (o mejor dicho, la pila de herramientas) de verificación formal TLA+. Se trata de una tecnología que, si bien aún no ha sido ampliamente adoptada, merece la pena apostar por ella dados sus grandes beneficios.Mi primera especificación en TLA+2019-07-08T00:00:00+00:002019-07-08T00:00:00+00:00http://jesusmg.org/primera-especificacion-TLAplus<p><a href="https://lamport.azurewebsites.net/tla/tla.html">TLA+</a> es un lenguaje de especificación formal. En otras palabras, se trata de un lenguaje de alto nivel que permite modelar algoritmos y sistemas, para posteriormente verificar programáticamente la ausencia de errores en dichos modelos.</p>
<p>Su principal desarrollador es <a href="https://es.wikipedia.org/wiki/Leslie_Lamport">Leslie Lamport</a>, sin desmerecer al resto de la comunidad que hay tras dicho lenguaje. Por supuesto es de código abierto, bajo licencia MIT.</p>
<p>He empezado a estudiar en serio este lenguaje, dada su utilidad y sus aplicaciones en el desarrollo seguro de software.</p>
<p>Una pregunta recurrente son las ventajas de un lenguaje de programación formal, como TLA+, frente a las pruebas unitarias clásicas.
Mientras que las pruebas unitarias (y otros tipos de pruebas) solo verifican el funcionamiento del programa para unos valores de entrada (escenario) determinado, un lenguaje formal verifica el funcionamiento y determinadas restricciones para todos los posibles estados del programa (¡incluso si se trata de programación concurrente!).</p>
<p><a href="https://lamport.azurewebsites.net/tla/formal-methods-amazon.pdf">Este artículo</a> muestra un caso de éxito interesante de aplicación de TLA+ en el desarrollo de componentes de AWS.</p>
<p>Como parte del proceso de aprendizaje me planteé modelar la siguiente especificación simple por mí mismo.</p>
<p>Sea la gestión de turnos de un hospital, donde:</p>
<ul>
<li>El hospital tiene una capacidad máxima de 10 personas.</li>
<li>La atención de las personas se clasifica en 5 niveles de prioridad.</li>
<li>Una persona puede acudir al hospital sin prioridad previa.</li>
<li>En el caso de que una persona venga en ambulancia o a través de otro hospital, traerá un nivel de prioridad previa asignado.</li>
<li>Si el hospital excede su capacidad, clasificará al paciente con una prioridad y será derivado a otro hospital.</li>
</ul>
<p>El hospital dispone de 5 médicos que organizan su trabajo según la siguiente lista de prioridad:</p>
<ol>
<li>Atender a los pacientes con prioridad 4 o 5.</li>
<li>Clasificar pacientes que no tengan un nivel de prioridad asignado.</li>
<li>Atender a los pacientes con nivel de prioridad 3 o inferior.</li>
<li>En caso de que el hospital se encuentre desbordado, se dará prioridad a la clasificación de pacientes y su derivación hasta volver a la capacidad máxima.</li>
</ol>
<p>En el momento de empezar a modelar la especificación, pensé que era correcta.</p>
<p>Sin embargo, al ejecutar una primera versión del modelo, TLC (el verificador de modelos de TLA+) reportó un error.
No había tenido en cuenta la posibilidad de que el hospital estuviese desbordado y todos los pacientes tuviesen prioridad asignada (es decir, no hay pacientes sin clasificar).</p>
<p>Para corregirlo, modifiqué el modelo para que en ese caso se atienda a los pacientes de la misma forma que si el hospital no estuviese desbordado.</p>
<p>Este es un ejemplo claro del tipo de fallos que TLA+ puede detectar.</p>
<p>He subido la especificación completa al siguiente repositorio de GitHub: <a href="https://github.com/jesmg/TLAplus-hospital">https://github.com/jesmg/TLAplus-hospital</a>.</p>TLA+ es un lenguaje de especificación formal. En otras palabras, se trata de un lenguaje de alto nivel que permite modelar algoritmos y sistemas, para posteriormente verificar programáticamente la ausencia de errores en dichos modelos.SuperSEC: Congreso nacional sobre desarrollo seguro de software2018-03-24T00:00:00+00:002018-03-24T00:00:00+00:00http://jesusmg.org/nota-prensa-supersec<p>En los próximos 12 y 13 de mayo se celebrará en el campus de la Universidad de Almería el congreso nacional sobre desarrollo seguro de software <a href="https://supersec.es">SuperSEC 2018</a>.</p>
<p>El congreso convoca a todo el sector profesional de la industria del software en general y de la programación en particular para concienciar, divulgar y promocionar la adopción de prácticas y herramientas que minimicen el potencial de futuros defectos y vulnerabilidades en los sistemas de información.</p>
<p>Así SuperSEC aspira a ser la convocatoria nacional de referencia en el futuro para toda la industria del software española. Para ello ha lanzado un llamamiento a la participación para que académicos y profesionales compartan sus experiencias y propuestas técnicas. A la vez está confeccionando un plantel de conferenciantes invitados de primer orden.</p>
<p>SuperSEC 2018 es una iniciativa sin ánimo de lucro del <a href="https://www.owasp.org/index.php/Almeria">grupo local OWASP Almería</a>.</p>
<ul>
<li>Web: <a href="https://supersec.es">https://SuperSEC.es/</a></li>
<li>Correo-e: <a href="mailto://hola@supersec.es">hola@SuperSEC.es</a></li>
<li>Grupo Telegram: <a href="https://t.me/SuperSEC">@SuperSEC</a></li>
<li>Twitter: <a href="https://twitter.com/supersec_es">@SuperSEC_ES</a></li>
</ul>En los próximos 12 y 13 de mayo se celebrará en el campus de la Universidad de Almería el congreso nacional sobre desarrollo seguro de software SuperSEC 2018.Código seguro en las jornadas SLCENT2017-11-16T00:00:00+00:002017-11-16T00:00:00+00:00http://jesusmg.org/charla-jornadas-slcent-2017<p>El pasado día 9 de noviembre, se celebró la decimocuarta edición de las <a href="http://hacklabalmeria.net/actividades/2017/11/09/xiv-jornadas-slcent.html">jornadas SLCENT</a> (Software libre, cultura emprendedora y nuevas tecnologías), destinadas a profesores y estudiantes de Formación Profesional, además de cualquier curioso que quiso acercarse.</p>
<p>Participé en las jornadas con la charla <em>Tu código apesta, y le voy a oler las vergüenzas</em>. Se trató de una introducción pragmática, y en tono sarcástico, a los olores del código.</p>
<p><img src="http://jesusmg.org/images/foto-slcent-17.jpeg" alt="Fotografía de la charla" title="Fotografía por Guillermo Fuertes" /></p>
<p>Así mismo, la charla intentó transmitir al público la cercana relación entre las buenas prácticas de desarrollo, y la seguridad del software.</p>
<p>Puedes ver la presentación utilizada en <a href="http://slcent17.jesusmg.org">este enlace</a></p>El pasado día 9 de noviembre, se celebró la decimocuarta edición de las jornadas SLCENT (Software libre, cultura emprendedora y nuevas tecnologías), destinadas a profesores y estudiantes de Formación Profesional, además de cualquier curioso que quiso acercarse.Fundado el grupo OWASP Almería2017-07-14T00:00:00+00:002017-07-14T00:00:00+00:00http://jesusmg.org/fundado-grupo-owasp-almeria<p>Ayer quedó fundado el <em>grupo local OWASP Almería</em>.</p>
<p>OWASP es una organización mundial, sin ánimo de lucro, que tiene por objetivo mejorar la seguridad del software. Para ello desarrollan herramientas, documentación y estándares, siempre con licencias libres.</p>
<p>El grupo local OWASP Almería tiene por objetivo difundir, concienciar y enseñar sobre seguridad del software en la provincia, a través de un grupo abierto y colaborativo.</p>
<p>Para más información, puedes visitar la <a href="https://www.owasp.org/index.php/Almeria">página oficial</a>, y suscribirte a la <a href="https://lists.owasp.org/mailman/listinfo/owasp-almeria">lista de correo</a>.</p>Ayer quedó fundado el grupo local OWASP Almería.Gestionando datos delicados en Java2017-04-01T00:00:00+00:002017-04-01T00:00:00+00:00http://jesusmg.org/gestionando-datos-delicados-Java<p>Cuando se desarrolla una aplicación que contiene <strong>datos sensibles</strong> (o, mejor dicho, delicados), el programador debe preguntarse si el entorno de ejecución es lo bastante seguro. La información a proteger, y la zona de memoria que ésta ocupa, se encontrarán a merced del nivel de aislamiento y del resto de aplicaciones ejecutándose en el sistema.</p>
<p><a href="https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure">Según OWASP</a>, la exposición de datos delicados es la sexta vulnerabilidad más frecuente.</p>
<p>A día de hoy y por regla general, no se duda de la necesidad de transmitir la información delicada a través de HTTPs. Sin embargo, <strong>es fácil olvidarse de los otros dos lugares donde puede ser expuesta</strong>: El servidor y el cliente. Especialmente al utilizar lenguajes administrados, donde el programador se despreocupa de la gestión de la memoria.</p>
<p>En el caso de Java, existen caractersticas que facilitan la solución del problema. En concreto, <strong>las cadenas mutables y los objetos sellados</strong>:</p>
<ul>
<li>
<p>El tipo String es un objeto inmutable. Es decir, al modificar el valor se crea una nueva copia del objeto en memoria, y la anterior persiste hasta que el recolector de basura decide llevársela.</p>
<p>Por ejemplo: Se crea una variable de tipo String, la cual almacena una contraseña válida, y posteriormente se reemplaza por un valor nulo. Un malware hace un volcado de memoria en ese momento, y manda los resultados para ser examinados. El usuario malicioso podría ver tanto el valor nulo como la contraseña, ocupando distintas posiciones.</p>
<p><strong>Un <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html">StringBuffer</a> es una cadena de caracteres mutable</strong>. Citando la documentación oficial, es cómo un String pero puede ser modificado. Es decir, los cambios afectan directamente a la zona de memoria reservada para esa variable. Esto otorga control total sobre la información almacenada, que puede sobrescribirse con datos no significativos (por ejemplo, una cadena de ceros) hasta que el recolector decida eliminarla.</p>
<p><strong>También se podría utilizar el objeto <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html">StringBuilder</a></strong>, cuyo funcionamiento es similar al del StringBuffer. Si bien las operaciones con el StringBuilder son más rápidas, no es apto para trabajar con múltiples hilos, al contrario que el StringBuffer.</p>
</li>
</ul>
<h6 id="ejemplo-crear-y-eliminar-un-stringbuffer">Ejemplo: Crear y eliminar un StringBuffer</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Crear nuevo StringBuffer</span>
<span class="nc">StringBuffer</span> <span class="n">password</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuffer</span><span class="o">();</span>
<span class="n">password</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">"contraseña del usuario"</span><span class="o">);</span>
<span class="c1">//Eliminar el string buffer</span>
<span class="n">password</span><span class="o">.</span><span class="na">delete</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">password</span><span class="o">.</span><span class="na">length</span><span class="o">());</span>
</code></pre></div></div>
<ul>
<li>
<p>Los <a href="https://docs.oracle.com/javase/7/docs/api/javax/crypto/SealedObject.html">SealedObject</a> son una característica de javax.crypto, la librería de Java para operaciones criptográficas. Se crean pasándoles otro objeto como parámetro. <strong>Una copia del objeto original se almacenará cifrada dentro del SealedObject</strong>.</p>
<p>Se puede encapsular cualquier objeto dentro del SealedObject, bajo la condición de que sea serializable. Además, el desarrollador puede indicar el cifrado que desea utilizar, entre todos los disponibles en la librería.</p>
</li>
</ul>
<h6 id="ejemplo-cifrar-en-un-sealedobject">Ejemplo: Cifrar en un SealedObject</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Crear un cifrador (AES con clave de 16 bytes)</span>
<span class="nc">Cipher</span> <span class="n">cifrador</span> <span class="o">=</span> <span class="nc">Cipher</span><span class="o">.</span><span class="na">getInstance</span><span class="o">(</span><span class="s">"AES/CBC/PKCS5Padding"</span><span class="o">);</span>
<span class="nc">SecureRandom</span> <span class="n">random</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SecureRandom</span><span class="o">();</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">clave</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="mi">16</span><span class="o">];</span>
<span class="n">random</span><span class="o">.</span><span class="na">nextBytes</span><span class="o">(</span><span class="n">clave</span><span class="o">);</span>
<span class="nc">SecretKeySpec</span> <span class="n">clavespec</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SecretKeySpec</span> <span class="o">(</span><span class="n">clave</span><span class="o">,</span> <span class="s">"AES"</span><span class="o">);</span>
<span class="n">cifrador</span><span class="o">.</span><span class="na">init</span><span class="o">(</span><span class="nc">Cipher</span><span class="o">.</span><span class="na">ENCRYPT_MODE</span><span class="o">,</span> <span class="n">clavespec</span><span class="o">);</span>
<span class="c1">//Crear un SealedObject y almacenar el StringBuffer usando el cifrador</span>
<span class="nc">SealedObject</span> <span class="n">passwordCifrada</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SealedObject</span><span class="o">(</span><span class="n">password</span><span class="o">,</span> <span class="n">cifrador</span><span class="o">);</span>
</code></pre></div></div>
<h6 id="ejemplo-descifrar-el-sealedobject">Ejemplo: Descifrar el SealedObject</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Recuperar la contraseña del SealedObject usando la clave del cifrador</span>
<span class="n">autenticarUsuario</span><span class="o">(</span><span class="n">passwordCifrada</span><span class="o">.</span><span class="na">getObject</span><span class="o">(</span><span class="n">clavespec</span><span class="o">));</span>
</code></pre></div></div>
<p>Las dos características que se han visto permiten gestionar la información delicada de manera sencilla y segura. En un posible caso de uso final, se almacenarían los datos en un StringBuffer, encapsulado en un SealedObject. A la hora de utilizar dichos datos en una operación, se descifraría el SealedObject obteniendo el StringBuffer original. Por último, se sobrescribiría el valor del StringBuffer para eliminarlo.</p>
<h6 id="ejemplo-código-final">Ejemplo: Código final</h6>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.security.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.crypto.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.crypto.spec.SecretKeySpec</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DatosDelicados</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">NoSuchAlgorithmException</span><span class="o">,</span> <span class="nc">NoSuchPaddingException</span><span class="o">,</span> <span class="nc">IllegalBlockSizeException</span><span class="o">,</span> <span class="nc">IOException</span><span class="o">,</span> <span class="nc">ClassNotFoundException</span><span class="o">,</span> <span class="nc">BadPaddingException</span><span class="o">,</span> <span class="nc">InvalidKeyException</span> <span class="o">{</span>
<span class="c1">//Crear nuevo StringBuffer</span>
<span class="nc">StringBuffer</span> <span class="n">password</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuffer</span><span class="o">();</span>
<span class="n">password</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">"contraseña del usuario"</span><span class="o">);</span>
<span class="c1">//Crear un cifrador (AES CBC con clave de 16 bytes)</span>
<span class="nc">Cipher</span> <span class="n">cifrador</span> <span class="o">=</span> <span class="nc">Cipher</span><span class="o">.</span><span class="na">getInstance</span><span class="o">(</span><span class="s">"AES/CBC/PKCS5Padding"</span><span class="o">);</span>
<span class="nc">SecureRandom</span> <span class="n">random</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SecureRandom</span><span class="o">();</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">clave</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="mi">16</span><span class="o">];</span>
<span class="n">random</span><span class="o">.</span><span class="na">nextBytes</span><span class="o">(</span><span class="n">clave</span><span class="o">);</span>
<span class="nc">SecretKeySpec</span> <span class="n">clavespec</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SecretKeySpec</span> <span class="o">(</span><span class="n">clave</span><span class="o">,</span> <span class="s">"AES"</span><span class="o">);</span>
<span class="n">cifrador</span><span class="o">.</span><span class="na">init</span><span class="o">(</span><span class="nc">Cipher</span><span class="o">.</span><span class="na">ENCRYPT_MODE</span><span class="o">,</span> <span class="n">clavespec</span><span class="o">);</span>
<span class="c1">//Almacenar el StringBuffer en el SealedObject usando el cifrador</span>
<span class="nc">SealedObject</span> <span class="n">passwordCifrada</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SealedObject</span><span class="o">(</span><span class="n">password</span><span class="o">,</span> <span class="n">cifrador</span><span class="o">);</span>
<span class="c1">//Eliminar el string buffer</span>
<span class="n">password</span><span class="o">.</span><span class="na">delete</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">password</span><span class="o">.</span><span class="na">length</span><span class="o">());</span>
<span class="c1">//Recuperar la contraseña del SealedObject usando la clave del cifrador</span>
<span class="n">autenticarUsuario</span><span class="o">(</span><span class="n">passwordCifrada</span><span class="o">.</span><span class="na">getObject</span><span class="o">(</span><span class="n">clavespec</span><span class="o">));</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">autenticarUsuario</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">object</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>Cuando se desarrolla una aplicación que contiene datos sensibles (o, mejor dicho, delicados), el programador debe preguntarse si el entorno de ejecución es lo bastante seguro. La información a proteger, y la zona de memoria que ésta ocupa, se encontrarán a merced del nivel de aislamiento y del resto de aplicaciones ejecutándose en el sistema.Hablando sobre código seguro en la PyConES 20162017-03-25T00:00:00+00:002017-03-25T00:00:00+00:00http://jesusmg.org/publicada-charla-pycones-2016<p>Ya ha sido publicado el video de mi charla <em>“Tu código apesta, pero puedes tomar medidas”</em>, en la pasada PyConES 2016.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/BHKhtgPYZEE?ecver=1" frameborder="0" allowfullscreen=""></iframe>
<p>También puedes ver el material utilizado en <a href="http://pycones16.jesusmg.org/#/">este</a> enlace.</p>Ya ha sido publicado el video de mi charla “Tu código apesta, pero puedes tomar medidas”, en la pasada PyConES 2016.¡Bienvenido!2017-01-29T00:00:00+00:002017-01-29T00:00:00+00:00http://jesusmg.org/bienvenido<p>Bienvenido a la nueva web.</p>Bienvenido a la nueva web.