Mostrando entradas con la etiqueta Seguridadde la información y criptografía. Mostrar todas las entradas
Mostrando entradas con la etiqueta Seguridadde la información y criptografía. Mostrar todas las entradas

jueves, 1 de noviembre de 2012

Result Steganography

The images that have information are:

code


letter 


url


The content of each one are: a letter, an url and the code of my program.


code:
from sys import argv
from PIL import Image

def openFile(fileName):
    f = open(fileName, 'r')
    mensaje = list()
    for line in f:
        mensaje.append(line)
    f.close()
    return "".join(mensaje)

def setMsn(mensaje):
    m2 = list()
    mensaje = list(mensaje)
    
    for i in mensaje:
        u = bin(ord(i))[2:].zfill(8)
        for j in u:
            m2.append(j)
    return m2

def getMsn(mensaje):
    m2 = list()
    a = 1
    b = ''
    for i in mensaje:
        b = b+i
        if(a%8 == 0):
            m2.append(chr(int(b,2)))
            b = ''
                       
        a = a + 1
    return "".join(m2)

def pixelF(m2, v, count):
    if(v[7:8] != m2[count]):
        v = v[:7]+m2[count]
    else:
        v = v
    return int(v, 2)
            
def openImage(fileName, m2):
    im = Image.open(fileName)
    rgb = im.convert('RGB')
    c = 0

    while c != len(m2)-1:
        for i in range(0, im.size[0], 3):
            for j in range(im.size[1]):
                b = rgb.getpixel((i, j))[2]
                v = bin(b)[2:].zfill(8)

                w = pixelF(m2, v, c)

                r = rgb.getpixel((i, j))[0]
                g = rgb.getpixel((i, j))[1]

                d = tuple([r,g,w])
                im.putpixel((i,j),d)
                if(c == len(m2)-1): break
                c = c+1
    im.save(str(2)+fileName, "PNG")

def decodeM(fileName):
    im = Image.open(fileName)
    rgb = im.convert('RGB')
    arrayRGB = list()

    for i in range(0, im.size[0], 3):
        for j in range(im.size[1]):
            b = rgb.getpixel((i, j))[2]
            v = bin(b)[2:].zfill(8)
            arrayRGB.append(v[7:8])
    return arrayRGB

def main():

    mensaje = openFile(argv[1])
    mensaje = setMsn(mensaje)
   
    imagen = argv[2]
    print imagen
    w = openImage(imagen, mensaje)

    m2 = decodeM(str(2)+imagen)
    print getMsn(m2)
    
main()


The code take 2 parameters, the name of the file that contains the information and the name of the image to save.
> criptoImage.py fileInformation.txt image.png > dInformation.txt

To decrypt we can use the next code:
 
from sys import argv
from PIL import Image

def getMsn(mensaje):
    m2 = list()
    a = 1
    b = ''
    for i in mensaje:
        b = b+i
        if(a%8 == 0):
            m2.append(chr(int(b,2)))
            b = ''
                       
        a = a + 1
    return "".join(m2)

def decodeM(fileName):
    im = Image.open(fileName)
    rgb = im.convert('RGB')
    arrayRGB = list()

    for i in range(0, im.size[0], 3):
        for j in range(im.size[1]):
            b = rgb.getpixel((i, j))[2]
            v = bin(b)[2:].zfill(8)
            arrayRGB.append(v[7:8])
    return arrayRGB

def main():

    m2 = decodeM(str(1)+imagen)
    print getMsn(m2)
    
main()

This code only takes the name of the image

miércoles, 24 de octubre de 2012

Stream Cipher - SOBER-128

Introduction:
The sober-128 stream cipher, was develop for Philip Hawkes, Michael Paddon and Gregory G. Rose, in Gladesville Australia for Qualcomm Autralia. (Curiosity, this same people develop Turing Cipher).

Why?
The reason by the article is have a stream cipher primitive constructor that having a some characteristics by:
  • quickly
  • easy
  • open source
  • secure
"SOBER-128 is based on simple 32 bit operations*. Keys and optional nonces of arbitrary length are supported. Enumeration of keys is thought to be the most efficient attack for key lengths of 128 bits or less. SOBER-128 may be configured to calculate an arbitrary length Message AuthenticationCode (MAC) as part of the encryption or decryption process." 

*(such as 32-bit XOR and addition modulo 232), and references to small fixed arrays.

Implementations
SOBER-128 is use in many computing environments (smart cards to large computers), but principally in mobile systems.

Description:
SOBER-128 is constructed from a linear feedback shift register (LFSR), a non-linear filter (NLF)* and a nonlinear plaintext feed back function (PFF)**.

* Is used to generate the keystream.
** Is used to perturb the LFSR when a MAC is desired.

Sober-128 operate in two modes:

  • Synchronous mode:
  • MAC (Message authentication mode:)

The first is use to when a MAC isn't required, where in the keystream generation is independent of the plaintext. And the second utilizes the PFF to perturb the LFSR with plaintext during encryption or decryption. After the message has been processed, the keystream generator is used to produce a MAC (MAC is required).

LFSR
This consists of 17 words of state, designated R[0] through R[16].

pseudocode:

Step(R):
              x = R[15] ^ R[4] ^ (R[0] << 8)
                  ^ Multab[(R[0] >> 24) & 0xff];
              for (i = 0 to 15):
                  R[i] = R[i + 1];
              R[16] = x;


Where Multab is a table of 256 constants.

NLF

pseudocode:

NLF(R, Konst) = f((((f(R[0] + R[16]) >>> 8) + R[1]) ^ Konst)
                          + R[6]) + R[13];



where "f" is a substitution box function and "Konst" is a constant that is calculated during cipher initialization. The function f is defined by:


f(x) = SBox[x >> 24] ^ x;



Where SBox is a table of 256 constants.

PFF
pseudocode:

PFF(R, Konst, x) = f((f(R[4] + x) >>> 8) + Konst);





Encryption and Decryption:
Encryption is achieved by producing a keystream, which is then combined with the plaintext. The keystream is generated in groups of 4 octets.
pseudocode:


        Step(R);
          x = NLF(R, Konst);
          for (i = 0 to 3):
              v[i] = x & 0xff;
              x = x >> 8;


Encryption:

        for (i = 0 to p.length - 1):
              c[i] = p[i] ^ v[i];


Decryption:

        for (i = 0 to p.length - 1):
              p[i] = c[i] ^ v[i];


*p is the plaintext
*c is the ciphertext
*v is the keystream

Security:
Searching in the web I found this comment in a forum, about the security:
"The base attack on SOBER-128 is an exhaustive key search, (complexity of 2^128).In all attacks, it is assumed that the attacker observes a certain amount of keystream produced by one or more secret keys, and the attacker knows the corresponding plaintext and nonces. This is considered to resist an attack if either the attack requires the owner of the secret key(s) to generate more than 2^80 key stream words, or the computational complexity of the attack is equivalent to the attacker rekeying the cipher 2^128 times and generating at least 5 words of output each time."

Code example:
c
java

Tables:
http://tools.ietf.org/html/draft-paddon-sober128-01#appendix-A
http://tools.ietf.org/html/draft-paddon-sober128-01#appendix-B

Referencias:
http://en.wikipedia.org/wiki/SOBER-128
http://tools.ietf.org/html/draft-paddon-sober128-01
https://opensource.qualcomm.com/index.php?sober128
https://opensource.qualcomm.com/assets/pdf/SOBER-128-v2.pdf
http://www.ietf.org/mail-archive/web/cfrg/current/msg00293.html
http://www.ietf.org/mail-archive/web/cfrg/current/msg00280.html

martes, 16 de octubre de 2012

Algoritmos Bloque/Bloque ciphers

Who and Where?
The new Block Cipher Rainbow, is the title of an article written by Chang-Hyi Lee and Jeong-Soo Kim in the  Samsung Advance Institute of Technology.

Type of math
Where propose another model of Block Cipher. This type of cipher has the substitution and permutation. similar to the block ciphers Square and SHARK 



Why?
In the article, the authors mention:
"the motivation for develop the algorithm came out from the hope that, first, the block cipher has the structure of parallelism, second, it has a self-reciprocal structure and third its round encryption  involves no linear and efficient key dependent diffusion layer".
The authors implement the algorithm and obtain that the proposal its acceptable, encrypting of 9 to 10mb/secs on a 133 MHz Pentium PC.

How it works?
This type of cipher works by 3 layers related to the round key active diffution and the others ones relates to the non linear sustitution with simple permutation.

G-Function
Where Xi are 32 bit subblocks and K be a 128 bit round key and  \oplus denotes bit by bit logic XOR.

B-Function
Taking that x and k are the same that the previous.

Where ^ denotes bit by bit logic AND.

R-Function
This function consists in 3 types of components functions, P1, P2, P3, which all are defined in the following as functions of the sub-data block, GF(2³²) to GF(2³²). Let x = (x3, x2, x1, x0), Xi \in GF(2⁸) and so x \in GF(2³²). Let's define:

f be a bijective nonlinear function of GF(2⁸) to GF(2⁸)

f and f⁻¹ tables:


Performance:

Comments
Searching I found that this type of cipher is mentioned by hackers for auditories of passwords and aplicated in telecommunications between satellites and smart cards.

References:

jueves, 20 de septiembre de 2012

HTTP RSA Implementation

Hi, for this week we needed to implement the algorithm rsa in a web service, for the activity I choose php for WS.

The dinamic between server and user is the next:
  • The server has e and n, this keys are public.
  • The user has n and d, where d is the private key.
  • When a user open the page, server generate a x random number.
  • The user use this number for generate a response(r), the response is generate for a script, provided for the server.
  • Then the user put this r in the service and the server compare r with a num produced.
  • If this is correct the users are welcome, else the users are denied.
Important points:
  • For generate r (user), need two functions f(x)  &  fastmodexp(x, y, mod).
    • where in my case f(x) return (x*2)+5, this can be a other ecuation.
    • fasmodexp is f(x)**d mod n
      • d is the private key.
  • In the autentification for the server we need to implement the same f(x), but this help us  to compare, use fasmodexp(r, e, n), where r is the response of the user and e & n is the public key.

Code:
home.php
rsaAutentification.php
validation.py
Tabla Usuarios

result:





WebService:
You can check the program in the next link: ....

Note:
Php is a pussy,  in my case when I use a big numbers the autentification fail, but checking in python the autentification is correct.


jueves, 30 de agosto de 2012

Diffie-Hellman hack

Para ésta entrada nos toco realizar una actividad en la que consistía tratar de sacar el mensaje y la clave emitidos por Alice & Bob.

Variables o valores a usar:
p: Es un número primo emitido por Alice & Bob (público)
g: Es un número cualquiera que pertenece a p (público)
X: Es el valor que obtiene Bob apartir de un x que el define (público)
Y: Es el valor que obtiene Alice apartir de un y que el define (público)

x: Es el valor definido por Bob (privado)
y: Es el valor definido por Alice (privado)
k: Es la clave (privada)

Fórmulas:




Actividad:
p = 29
g = 19
X = 21
Y = 6

Para ésta actividad, realice un programa en python en la cuál me devuelve el valor de x, y & k. Así que la idea para sacarlas emplie fuerza bruta buscando el valor y comprobando ésta con X o Y y una vez tenidas éstas sustitui en la fórmula.

x = g ^ (i) mod p
y = g ^ (i) mod p


e i comprobábamos que fuera igual a X & Y y una vez tenidos éstas sustituiamos en la fórmula para obtener k


Programa:
def sacarX(p,g,x):
    for i in range(p):
        newX = (g**i)%p
        if newX == x:
            print "x: "+str(i)
            return i

def sacarY(p,g,y):
    for i in range(p):
        newX = (g**i)%p
        if newX == y:
            print "y: "+str(i)
            return i

def sacarK(g,p,x,y):
    k = (g**(x*y))%p
    print "K vale: "+str(k)


p = 29
g = 19
x = 21
y = 6

x = sacarX(p,g,x)
y = sacarY(p,g,y)
sacarK(g,p,x,y)




Resultados:




Referencias:
http://es.wikipedia.org/wiki/Diffie-Hellman

miércoles, 29 de agosto de 2012

Prueba de aleatoriedad clave One Time Pad

¿Para que nos serviría hacer una prueba de aleatoriedad para la clave generada?
La respuesta, es que si nosotros (que claro que si) estamos buscando generar una clave que sea dificil de romper o descifrar, a nosotros nos interesaría hacer éste tipo de test.

¿Pero como sabríamos si es aleatoria?
No sabemos bien si un número es totalmente aleatorio entonces lo que se hace es medir las frecuencias que estamos recibiendo.
En ésto me ayudo mucho en ver de otra forma, una caricatura que encontré en random.org


Para esto hay diferentes tipos de pruebas como anderson, chi, monobit, de bloques, run, entre otras. Cada una la aplicamos dependiendo del tipo de test que estamos buscando y su número aleatorio.

Para esta entrada se genero los números aleatorios de one time pad, donde buscaremos verificar que tan aleatorio es nuestra clave.

Prueba
El tipo de prueba empleado es el monobit, el cúal su fórmula ésta dada por:

Donde E es nuestra secuencia de bits
Sn nuestra sumatoria de E (hay que indicar que nuestra, que al momento de identificar un 0 esto lo cambia a -1)
n es nuestro tamaño total de E
P-value será tomada con erfc(sobs/sqrt(2))
donde erfc es la función de error complementario.
Ya para definir si fue aleatorio, se compara con una muestra de 0.01 y si esta es mayor la prueba pasa, de lo contrario no es aleatorio.


Código nuevo:

from random import randint
from math import sqrt, erfc

def generarClaves(cantidad, nombre):
    a = 'abcdefghijklmnopqrstuvwxyz '
    largoClave = 80
    for i in range(cantidad):
        clave = list()
        for j in range(largoClave):
            letra = randint(0, len(a)-1)#Creamos nuestro numero aleatorio del tamano del arreglo
            clave.append(letra)
        pruebasRand(clave)#mandamos llamar al metodo de pruebas
        #print clave

#clave.append("\n")
        #guardarClaves(clave, nombre)
def pruebasRand(clave):
    print "Prueba Monobit"
    print "\t Resultado:"+str(pruebaMonobit(clave))

def pruebaMonobit(clave):
    s = list()
    for i in clave:
        i = convertirUnosCeros(i) #Leemos cada elemento del arreglo para sacar unos y ceros
        s.append(i)
    sobs = abs(sum(s))/sqrt(len(s)) #Aplicamos la formula propuesta
    pValue = erfc(sobs/sqrt(2)) #Aplicamos la formula propuesta
    if(pValue > 0.01): return "Prueba pasada "+str(pValue) #Comparamos
    else: return "Prueba no pasada "+str(pValue)

def convertirUnosCeros(elemento):
    elemento = elemento % 2 #Lo sacamos tomando los numero pares e impares
    if elemento == 0: return -1 #Si el elemento es 0 lo convertimos a -1 para que este afecte en la sumatoria
    else: return 1

def guardarClaves(clave, nombre):
    clave = "".join(clave)
    archivo = open(str(nombre), "a")
    archivo.write(clave)
    archivo.close()
    otro = open("copia"+str(nombre), "a")
    otro.write(clave)
    otro.close()

cantidad = int(raw_input("Dame la cantidad de claves a generar: "))
nombre = raw_input("Dame el nombre del archivo: ")
generarClaves(cantidad, nombre)

Explicamos:jninininia..

Resultados:
Así que ahora proseguimos a verificar nuestros resultados y para verificarlos que estuvieran bien, la prueba se hizo varias veces:

1 vez:

5 veces:

Así que por lo valores arrojados, podríamos decir que nuestro generador de claves es seguro y es aleatorio.

Nota:
¿Pero que pasa si al test lo aplicamos más de 5 veces? Pues sorpresa, descubrimos que nuestro generador de números aleatorios, no es del todo aleatorio. Aunque nuestros resultados digan que pasaron la prueba, podemos observar que sus resultados se van repitiendo, hasta tenemos una que otra, que no paso la prueba y sus resultados son los mismos.


Resultado: FAIL.
Ya con ésto sabemos que tristemente nuestra clave no es aleatoria, ya que se repite la frecuencia, así que el posible problema es al momento de emplear randint de python, así que para solucionar ésto, podríamos implementar un número random uniforme, obteniedo unos mejores resultados o hacer nuestro número con lo visto de simulación, así que más adelante pondré mi código mejorado.


Como podemos ver en la imágen los números generados (fueron 10000), se van repitiendo con una frecuencia, haciendo esto muy inseguro.

Referencia:
http://goo.gl/IP3Wx
http://goo.gl/ExMC6
http://www.random.org/analysis/
http://www.random.org/analysis/Analysis2005.pdf

jueves, 23 de agosto de 2012

Tarea: One Pad Time

Para esta entrada, se nos encargo hacer un programa que hiciera one time pad, a continuación les dejo el código:

Generador de claves:

from random import randint

def generarClaves(cantidad, nombre):
    a = 'abcdefghijklmnopqrstuvwxyz '
    largoClave = 80
    for i in range(cantidad):
        clave = list()
        for j in range(largoClave):
            letra = a[randint(0, len(a)-1)]
            clave.append(letra)
        clave.append("\n")
        guardarClaves(clave, nombre)

def guardarClaves(clave, nombre):
    clave = "".join(clave)
    archivo = open(str(nombre), "a")
    archivo.write(clave)
    archivo.close()
    otro = open("copia"+str(nombre), "a")
    otro.write(clave)
    otro.close()

cantidad = int(raw_input("Dame la cantidad de claves a generar: "))
nombre = raw_input("Dame el nombre del archivo: ")
generarClaves(cantidad, nombre)

Encriptacion-Desencriptación:

def main(mensaje, nombreA):
    clave = convertirMensajeAnsi(leerArchivo(nombreA))
    mensaje = convertirMensajeAnsi(mensaje)
    opcion = raw_input('Escoge 1 encriptar, 2 desencriptar: ')
    if(opcion == '1'):
        enc = "".join(modulo(mensaje, clave))
        print "encriptado: "+str(enc)
    if(opcion == '2'):
        des = "".join(moduloD(mensaje, clave))
        print "desencriptdo: "+str(des)

def modulo(mensaje, clave):
    enc = list()
    for i in range(len(mensaje)):
        enc.append(encriptar(mensaje[i], clave[i]))
    return enc

def moduloD(mensaje, clave):
    enc = list()
    for i in range(len(mensaje)):
        enc.append(desencriptar(mensaje[i], clave[i]))
    return enc

def encriptar(mensaje, clave):
    enc = int((int(mensaje) + int(clave))%123)
    return chr(enc)

def desencriptar(mensaje, clave):
    enc = int((int(mensaje) - int(clave))%123)
    return chr(enc)

def convertirMensajeAnsi(mensaje):    
    a = list()
    for letra in mensaje:
        ansi = str(ord(letra))
        if(len(ansi) < 3): ansi = "0"+str(ansi) 
        a.append(ansi)
    return a

def leerArchivo(nombreA):
    archivo = open(str(nombreA), 'r+')
    linea = archivo.readline()
    raw_input()
    nuevo = "".join(archivo.readlines()[0:])
    open('b.txt', 'w+').write(nuevo)
    return linea


mensaje = raw_input("Ingresa el mensaje: ")
nombreA = raw_input("Ingresa el nombre del archivo que cont. claves: ")
main(mensaje, nombreA)

Imagen:
Les dejo una captura de una prueba que hice.


Comentarios:
Me falta pulir un poco más el código, ya que unos métodos se repiten o algunas lineas que se pueden simplificar u optimizar.

jueves, 9 de agosto de 2012