elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


  Mostrar Temas
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 19
1  Seguridad Informática / Criptografía / Algoritmo DES (Data Encryption Standard) explicado paso a paso. en: 6 Febrero 2022, 09:30 am
Cifrado DES Explicado by StringManolo

DES (Data Encryption Standard) es un algoritmo de cifrado por bloques ya en desuso en su versión clásica, aunque en teoría su versión tripleDES es "segura", no se recomienda su uso debido a que hay alternativas mas seguras y rápidas. Aún así vale la pena conocer como funciona. La versión TripleDES no es mas que cifrar 3 veces el mensaje con DES.

- En el cifrado simétrico por bloques DES se utiliza una clave de 64 caracteres como entrada

Por ejemplo la clave en ASCII/UTF-8 (abcdefgh)
Cada caracter en esta clave se represta usando 1 byte (8 bits).
ASCII -> abcdefgh
Binario -> 01100001 01100010 01100011 01100100 01100101 01100110 01100111 01101000
Secuencia -> 0110000101100010011000110110010001100101011001100110011101101000

Código
  1. /* Ejemplo de codigo para convertir texto a binario */
  2.  
  3. const text = "abcdefgh";
  4. let end = "";
  5. for (let i in text) {
  6.  let aux = text[i].charCodeAt(0).toString(2)
  7.  if (aux.length < 8) {
  8.    aux = "0".repeat(8 - aux.length) + aux;
  9.  }
  10.  end += aux + " ";
  11. }
  12. console.log(end);

El algoritmo de DES ignora un bit por cada byte de la clave. Se cree que fue una estrategia de la NSA para poder romper el cifrado antes que nadie. Asique el tamaño de clave real utilizado internamente es de 56 bits aunque la entrada requiera de 64 bits.

- El algoritmo de DES usa tablas predefindas recurrentemente para realizar permutaciones. Se conocen como PC (Permuted Choice)

La primera tabla de permutación de DES es la siguiente (PC-1):
Cita de: PC-1
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4

Esta tabla nos indica la posición que debemos elegir de nuestra clave para generar la clave permutada de 56 bits a partir de la de 64 bits.

Nuestro binario es:
0110000101100010011000110110010001100101011001100110011101101000

Vamos a elegir el bit de la posición 57, después el que se encuentre en la posición 49 y así hasta finalizar toda la tabla.

Cita de: Permutaciones
57 -> 0
49 -> 0
41 -> 0
33 -> 0
25 -> 0
17 -> 0
9  -> 0

1  -> 0
58 -> 1
50 -> 1
42 -> 1
34 -> 1
26 -> 1
18 -> 1

10 -> 1
2  -> 1
59 -> 1
51 -> 1
43 -> 1
35 -> 1
27 -> 1

19 -> 1
11 -> 1
3  -> 1
60 -> 0
52 -> 0
44 -> 0
36 -> 0

63 -> 0
55 -> 1
47 -> 1
39 -> 0
31 -> 0
23 -> 1
15 -> 1

7  -> 0
62 -> 0
54 -> 1
46 -> 1
38 -> 1
30 -> 1
22 -> 0

14 -> 0
6  -> 0
61 -> 1
53 -> 0
45 -> 0
37 -> 0
29 -> 0

21 -> 0
13 -> 0
5  -> 0
28 -> 0
20 -> 0
12 -> 0
4  -> 0

Y aquí tenemos nuestra clave permutada de 56 bits con PC-1:
0000000
0111111
1111111
1110000
0110011
0011110
0010000
0000000

- El siguiente paso es divir la clave por la mitad en 2 trozos de 28 bits cada uno:
0000000
0111111
1111111
1110000

0110011
0011110
0010000
0000000

- El siguiente paso es aplicar una operación de cambio de bits hacia la izquierda a cada uno de los trozos para crear 2 grupos formados por 16 secuencias de bits cambiados.

La operación de cambio de bits hacia la izquiera se realiza moviendo cada bit hacia la izquierda pasando el que se encuentra en la primera posición al final del todo. Por ejemplo si tenemos la secuencia de bits 1101:
0° -> 1101
1° -> 1011
2° -> 0111
3° -> 1110
4° ...
5° ...

No todas las iteraciones tienen la misma cantidad de cambio de bits.
El número de bits por iteración que tenemos que desplazar hacia la izquierda es el siguiente:
Cita de: Bits desplazados por cada iteración
1°  -> 1 bit
2°  -> 1 bit
3°  -> 2 bits
4°  -> 2 bits
5°  -> 2 bits
6°  -> 2 bits
7°  -> 2 bits
8°  -> 2 bits
9°  -> 1 bit
10° -> 2 bits
11° -> 2 bits
12° -> 2 bits
13° -> 2 bits
14° -> 2 bits
15° -> 2 bits
16° -> 1 bit


El resultado es:

Cita de: Grupo 1: (Primera mitad de 28 bits)
0°  -> 0000000011111111111111110000
1°  -> 0000000111111111111111100000
2°  -> 0000001111111111111111000000
3°  -> 0000111111111111111100000000
4°  -> 0011111111111111110000000000
5°  -> 1111111111111111000000000000
6°  -> 1111111111111100000000000011
7°  -> 1111111111110000000000001111
8°  -> 1111111111000000000000111111
9°  -> 1111111110000000000001111111
10° -> 1111111000000000000111111111
11° -> 1111100000000000011111111111
12° -> 1110000000000001111111111111
13° -> 1000000000000111111111111111
14° -> 0000000000011111111111111110
15° -> 0000000001111111111111111000
16° -> 0000000011111111111111110000

Cita de: Grupo 2: (Segunda mitad de 28 bits)
0°  -> 0110011001111000100000000000
1°  -> 1100110011110001000000000000
2°  -> 1001100111100010000000000001
3°  -> 0110011110001000000000000110
4°  -> 1001111000100000000000011001
5°  -> 0111100010000000000001100110
6°  -> 1110001000000000000110011001
7°  -> 1000100000000000011001100111
8°  -> 0010000000000001100110011110
9°  -> 0100000000000011001100111100
10° -> 0000000000001100110011110001
11° -> 0000000000110011001111000100
12° -> 0000000011001100111100010000
13° -> 0000001100110011110001000000
14° -> 0000110011001111000100000000
15° -> 0011001100111100010000000000
16° -> 0110011001111000100000000000

- Lo siguiente es agruparlos juntos:
Cita de: Agrupados
1°  -> 0000000111111111111111100000 1100110011110001000000000000
2°  -> 0000001111111111111111000000 1001100111100010000000000001
3°  -> 0000111111111111111100000000 0110011110001000000000000110
4°  -> 0011111111111111110000000000 1001111000100000000000011001
5°  -> 1111111111111111000000000000 0111100010000000000001100110
6°  -> 1111111111111100000000000011 1110001000000000000110011001
7°  -> 1111111111110000000000001111 1000100000000000011001100111
8°  -> 1111111111000000000000111111 0010000000000001100110011110
9°  -> 1111111110000000000001111111 0100000000000011001100111100
10° -> 1111111000000000000111111111 0000000000001100110011110001
11° -> 1111100000000000011111111111 0000000000110011001111000100
12° -> 1110000000000001111111111111 0000000011001100111100010000
13° -> 1000000000000111111111111111 0000001100110011110001000000
14° -> 0000000000011111111111111110 0000110011001111000100000000
15° -> 0000000001111111111111111000 0011001100111100010000000000
16° -> 0000000011111111111111110000 0110011001111000100000000000

Y aplicar otra permutación con una nueva tabla (PC-2) para obtener 48 bits a partir de estos 56 que tenemos.
La tabla PC-2 es:
Cita de: PC-2
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32

Hay que aplicar esta tabla a cada uno de los 16 grupos para obtener un total de 16 claves de 48 bits cada una. Se hace igual que la primera permutación anteriormente mostrada con la tabla PC-1.

1°  -> 00000001111111111111111000001100110011110001000000000000

Cita de: Permutaciones
14 -> 1
17 -> 1
11 -> 1
24 -> 0
1  -> 0
5  -> 0

3  -> 0
28 -> 0
15 -> 1
6  -> 0
21 -> 1
10 -> 1

23 -> 1
19 -> 1
12 -> 1
4  -> 0
26 -> 0
8  -> 1

16 -> 1
7  -> 0
27 -> 0
20 -> 1
13 -> 1
2  -> 0

41 -> 0
52 -> 0
31 -> 0
37 -> 1
47 -> 0
55 -> 0

30 -> 1
40 -> 1
51 -> 0
45 -> 0
33 -> 1
48 -> 0

44 -> 1
49 -> 0
39 -> 1
56 -> 0
34 -> 1
53 -> 0

46 -> 0
42 -> 0
50 -> 0
36 -> 0
29 -> 1
32 -> 0

1°:
111000  
001011
111001
100110
000100
110010
101010
000010

Tienes que repetir este paso para el resto de las 16 secuencias. El proceso de los 15 restantes es omitido por brevedad, solo se mostrarán los resultados directamente.

Aquí el código que hice para no tener que realizarlas a mano:

Código
  1. /* PC a binario */
  2. const pc = (bin, table) => {
  3.  let result = "";
  4.  for(let i = 0; i < table.length; ++i) {
  5.    result += bin[table[i] - 1];
  6.  }
  7.  
  8.  return result;
  9. }
  10.  
  11.  
  12. const BIN = "00000001111111111111111000001100110011110001000000000000";
  13. const DES_PC2 = [
  14.  14, 17, 11, 24, 1, 5,
  15.  3, 28, 15, 6, 21, 10,
  16.  23, 19, 12, 4, 26, 8,
  17.  16, 7, 27, 20, 13, 2,
  18.  41, 52, 31, 37, 47, 55,
  19.  30, 40, 51, 45, 33, 48,
  20.  44, 49, 39, 56, 34, 53,
  21.  46, 42, 50, 36, 29, 32
  22. ];
  23.  
  24. const res = pc(BIN, DES_PC2);
  25. console.log(res);
  26. /* FIN DEL CÓDIGO */

Para calcular todas las secuencias, el código que añadí es:
Código
  1. /* Calcula las 16 secuencias con PC-2 */
  2. const BINS = [
  3.  "00000001111111111111111000001100110011110001000000000000",
  4.  "00000011111111111111110000001001100111100010000000000001",
  5.  "00001111111111111111000000000110011110001000000000000110",
  6.  "00111111111111111100000000001001111000100000000000011001",
  7.  "11111111111111110000000000000111100010000000000001100110",
  8.  "11111111111111000000000000111110001000000000000110011001",
  9.  "11111111111100000000000011111000100000000000011001100111",
  10.  "11111111110000000000001111110010000000000001100110011110",
  11.  "11111111100000000000011111110100000000000011001100111100",
  12.  "11111110000000000001111111110000000000001100110011110001",
  13.  "11111000000000000111111111110000000000110011001111000100",
  14.  "11100000000000011111111111110000000011001100111100010000",
  15.  "10000000000001111111111111110000001100110011110001000000",
  16.  "00000000000111111111111111100000110011001111000100000000",
  17.  "00000000011111111111111110000011001100111100010000000000",
  18.  "00000000111111111111111100000110011001111000100000000000"
  19. ];
  20.  
  21. for (let i in BINS) {
  22.  console.log( pc(BINS[i], DES_PC2) )
  23. }
  24. /* FIN DEL CÓDIGO */

Y el resultado es:
1°  -> 111000001011111001100110000100110010101010000010
2°  -> 111000001011011001110110000100000010001100000111
3°  -> 111001001101011001110110101101100000000010000100
4°  -> 111001101101001101110010010000000010001111000011
5°  -> 101011101101001101110011001101101010000000001001
6°  -> 101011110101001101011011011000100001010101000010
7°  -> 001011110101001111011001000011001010000100101010
8°  -> 000111110101100111011001011001000101110001000000
9°  -> 000111110100100111011001010010101001100001000000
10° -> 000111110110100110011101110000001100010100111000
11° -> 000111110010110110001101000010010001111000001000
12° -> 010110110010110010101101110110000101000000110000
13° -> 110110011010110010101100000000010100101000101100
14° -> 110100001010111010101110100100000011100010010000
15° -> 111100001011111000100110101000010000001000110101
16° -> 111100001011111000100110101000110100001010000000


- En DES el mensaje que quieres encryptar debe ser dividido en bloques de 64 bits.

Para el mensaje debemos realizar una permutación inicial con una nueva tabla IP (Initial Permutation):
Cita de: IP
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7

Usaré el mensaje "hello world" como ejemplo:
h -> 01101000
e -> 01100101
l -> 01101100
l -> 01101100
o -> 01101111
  -> 00100000
w -> 01110111
o -> 01101111
r -> 01110010
l -> 01101100
d -> 01100100

En bloques de 64 bits es:
0110100001100101011011000110110001101111001000000111011101101111
011100100110110001100100

Aquí tenemos un bloque de 64 bits y otro de 24.
Para no complicar el proceso con el padding, rellenaré de ceros el resto del bloque hasta alcanzar los 64 bits.
0110100001100101011011000110110001101111001000000111011101101111
0111001001101100011001000000000000000000000000000000000000000000

Ahora se aplica la tabla de permutación inicial (IP) a cada bloque:
B1 -> 1101111101000000110111101101001000000000111111111001110111010000
B2 -> 0000011100000001000001100000000000000000000001110000001000000001


- Ahora se divide cada bloque a la mitad (32 bits).

L  -> 11011111010000001101111011010010
R -> 00000000111111111001110111010000

(Este segundo bloque lo ignoraremos, porque hay distintas formas de combinar bloques, que esto ya no entra dentro de lo que es el propio algoritmo de DES y necesitaría una entrada propia)
L  -> 00000111000000010000011000000000
R -> 00000000000001110000001000000001

- El siguiente paso es utilizar una función que toma como entradas una clave de 48 bits y un texto de 32 bits, para generar una salida de 32 bits.
Usaremos las 16 claves de 48 bits que computamos en los pasos anteriores y los trozos de 32 bits que acabamos de hacer partiendo el mensaje en 2. Necesitamos aplicar las 16 claves a cada mitad usando una función.

Las claves que ya teníamos:
1°  -> 111000001011111001100110000100110010101010000010
2°  -> 111000001011011001110110000100000010001100000111
3°  -> 111001001101011001110110101101100000000010000100
4°  -> 111001101101001101110010010000000010001111000011
5°  -> 101011101101001101110011001101101010000000001001
6°  -> 101011110101001101011011011000100001010101000010
7°  -> 001011110101001111011001000011001010000100101010
8°  -> 000111110101100111011001011001000101110001000000
9°  -> 000111110100100111011001010010101001100001000000
10° -> 000111110110100110011101110000001100010100111000
11° -> 000111110010110110001101000010010001111000001000
12° -> 010110110010110010101101110110000101000000110000
13° -> 110110011010110010101100000000010100101000101100
14° -> 110100001010111010101110100100000011100010010000
15° -> 111100001011111000100110101000010000001000110101
16° -> 111100001011111000100110101000110100001010000000

El algoritmo que necesitamos utilizar es:
Código
  1. L[n] = R[n - 1]
  2. R[n] = L[n - 1] XOR F(R[n - 1], K[n])
L es el trozo izquierdo del bloque recientemente permutado
R es el trozo derecho del bloque recientemente permutado
XOR es una operación de Bits (Disyunción Exclusiva en Español).
F es una función con múltiples pasos que se detallará en seguida.
K es la clave.
n es la iteración/ronda.


Algoritmo para n = 1 (la primera vez que aplicas el algoritmo):
Código
  1. n = 1;
  2. L[1] = R[0];
  3. R[1] = L[0] XOR F(R[0], K[1]);

Código
  1. n = 1:
  2. R[0] = 00000000111111111001110111010000;
  3. L[1] = R[0]
  4. R[1] = 11011111010000001101111011010010 + F(00000000111111111001110111010000, 111000001011111001100110000100110010101010000010)

- Ahora vamos a empezar con la función F:

La función F utiliza una tabla de permutaciones (E) para expandir R[n - 1] de 32 bits a 48 bits.
Cita de: E
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1

En esta primera ronda, R[0] es 00000000111111111001110111010000

Tras expandir R[0] usando la tabla (E) para realizar la permutación, se obtiene:
000000000001011111111111110011111011111010100000

- El siguiente paso de la función es realizar un XOR entre R[0] expandido y K[1] (La primera clave)
000000000001011111111111110011111011111010100000 XOR 111000001011111001100110000100110010101010000010 -> 111000001010100110011001110111001001010000100010

El siguiente paso de F incluye el uso de S-Boxes (cajas de substitución).
Primero, hay que dividir el resultado de la clave xoreada con la mitad expandida del mensaje permutado en grupos de 6 bits:
111000 001010 100110 011001 110111 001001 010000 100010

La primera S-Box (S1) es:
Cita de: S1
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13

La S-Box es como un mapa de coordenadas. Hay que elegir el primer y el último bit de cada grupo de 6 bits para obtener la coluna y los bits restantes (en el medio) se utilizan para elegir la fila.
En el caso de 111000:
Primer y último bit -> 10
Bits del medio -> 1100

Los pasamos a decimal:
10 -> 2
1100 -> 12

Y ahora empleamos estos 2 números como guía para obtener el decimotercero número de la tercera columna (Las columnas y filas empiezan a contar en 0).

El número que obtenemos es el 3.
3 -> 0011

Es decir, usando la S-Box con 111000 como entrada, obtenemos como salida 0011.

Ahora tenemos que repetir lo mismo para el resto de grupos de 6 bits, PERO necesitamos utilizar una S-Box distinta para cada grupo.

Cita de: Las 8 S-Boxes (una para cada grupo de 6 bits)
 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
  
  15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
  
  10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
  
  7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
      
  2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
  
  12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
  
  4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
  
  13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11

Aquí el código que utilicé para generar todos los bits, utilizando los grupos y las cajas de substitución:
Código
  1. const transformSboxes = (groups, sboxes) => {
  2.  const ret = [];
  3.  for (let i in groups) {
  4.    const column = parseInt(groups[i][0] + groups[i][5], 2);
  5.    const field = parseInt(groups[i].substring(1, 5), 2);
  6.    let res = sboxes[i][column][field].toString(2);
  7.    if (res.length < 4) {
  8.      res = "0".repeat(4 - res.length) + res;
  9.    }
  10.    ret.push(res);
  11.  }
  12.  
  13.  return ret;
  14. }
  15.  
  16. const groups = [
  17.  "111000",
  18.  "001010",
  19.  "100110",
  20.  "011001",
  21.  "110111",
  22.  "001001",
  23.  "010000",
  24.  "100010"
  25. ]
  26.  
  27. const sBox = [
  28.  
  29.  [
  30.    [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
  31.    [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
  32.    [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
  33.    [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]               ],
  34.  
  35.  [
  36.    [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
  37.    [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
  38.    [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
  39.    [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]
  40.  ],
  41.  
  42.  [
  43.    [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
  44.    [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
  45.    [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
  46.    [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]
  47.  ],
  48.  
  49.  
  50.  [
  51.    [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
  52.    [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
  53.    [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
  54.    [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]
  55.  ],
  56.  
  57.  [
  58.    [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
  59.    [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
  60.    [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
  61.    [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]
  62.  ],
  63.  
  64.  [
  65.    [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
  66.    [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
  67.    [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
  68.    [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]
  69.  ],
  70.  
  71.  [
  72.    [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
  73.    [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
  74.    [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
  75.    [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]
  76.  ],
  77.  
  78.  [
  79.    [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
  80.    [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
  81.    [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
  82.    [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]
  83.  ]
  84. ];
  85.  
  86.  
  87. const res = transformSboxes(groups, sBox);
  88. console.log(res);
  89. /* END CODE */

Resultado:
0011 1011 1001 0001 1001 0111 0011 1011

De momento tenemos:
R[1] = 11011111010000001101111011010010 XOR F(0011 1011 1001 0001 1001 0111 0011 1011)

El último paso de la función es otra permutación:
Cita de: P
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25

El resultado de F es 11101111001010100110111100001010

Ahora tenemos que hacer xor a L[0] y al resultado de F para obtener R[1]:
R[1] = 11011111010000001101111011010010 XOR 11101111001010100110111100001010
R[1] -> 00110000011010101011000111011000

Ya finalizamos la primera ronda para n = 1. Recuerda:
Cita de: Algoritmo para n = 1
n = 1
L[1] = R[0]
R[1] = L[0] XOR F(R[0], K[1])

Ahora hay que realizar los mismos pasos para n = 2:
Cita de: Algoritmo para n = 2
n = 2
L[2] = R[1]
R[2] = L[1] XOR F(R[1], K[2])

Cuando finalizes todas las rondas (16), tendrás L[16] y R[16] (32 bits cada uno)
Solo te faltará darle la vuelta al orden. Ejemplo
Si L[16] es 00110000011010101011000111011000 y R[16] es 10110000011010101011000111011001 tendrás:
1011000001101010101100011101100100110000011010101011000111011000

Y aplicas la última permutación
Cita de: P-1
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25

El resultado es tu mensaje cifrado con DES.

Para descifrar es exactamente lo mismo.
2  Foros Generales / Foro Libre / Feliz 2022 en: 1 Enero 2022, 00:46 am
Feliz año nuevo!  :)
3  Programación / Scripting / Correr javascript en la terminal. en: 12 Diciembre 2021, 03:32 am
Hice un comando para poder correr javascript en la terminal.

Necesitas node/npm

Lo instalas con el comando:
npm install --global command-javascript

Ejemplos:

$ js 'console.log("Hello world")'

$ date | js 'console.log(pipedStdin.split(" ")[3])'

$ js 'console.log(run("curl --silent http://example.com"))' | wc -w

Ventajas:
- El código permanece en el historial. (Para mover con las flechas)
- Forma rápida de ejecutar javascript
- Incluye una función run para correr comandos directamente desde el código js
- Te permite mezclar shell y javascript pudiendo obtener input de otros comandos para manipularlo.
- Puedes añadir tus funciones custom añadiendo código a la función javascriptFunctions del programa. Así las tendrás disponibles en la terminal.
4  Programación / Bases de Datos / Como consultar un trozo de un parámetro en varias tablas? en: 5 Diciembre 2021, 00:32 am
Chicos, sabeis si hay algún tipo de consulta para sacar records de todas las tablas que coincidan con parte de un parámetro?

Con un ejemplo se entiende mejor.

Quiero que al poner en una barra de búsquedas:

man

Consultar la base de datos para sacar de la tabla usuarios:
manolo, manuel, mani, ...

Y de la tabla grupos:
manuales, como hacer manualidades,  las manzanas de oro, ...

Mi duda es si sql tiene alguna forma de hacer esto, o si por el contrario tengo que leer todas las entradas de la tabla y comparar usando un lenguaje de programación para mostrar los resultados.
5  Programación / Bases de Datos / Como debería organizar la información? Postgresql en: 27 Noviembre 2021, 17:55 pm
Estoy creando una red social usando postgresql y node. Tengo dudas a cerca de como debería organizar los datos. Esta es mas o menos toda la información  que quiero almacenar:
numero_telefono, correo, nombre_usuario, contraseña, nombre, primer_apellido, segundo_apellido, genero, pais, ciudad, enlace_foto_perfil, codigo_verificacion, esta_activo, esta_reportado, esta_bloqueado, fecha_creacion, fecha_actualizacion, biografia, mensajes_privados, mensajes_publicos, amigos, grupos, perfil_publico_o_privado, ...

Probablemente necesite añadir mas información como puedan ser ajustes, reportes y lo típico de una red social.

Mi duda es como debería organizar esta información. Creo solo una tabla usuarios? Multiples tablas con el mismo id?

Cualquier consejo es bienvenido.
6  Seguridad Informática / Análisis y Diseño de Malware / Cómo puedo evitar la detección por los AV? en: 1 Noviembre 2021, 04:41 am
Hice un crypter cli (comando) en C# al que le pasas la ruta de un exe como argumento y te genera un código (listo para compilar) que descifra y ejecuta el exe en memoria para evitar detecciones estáticas.

Por lo que parece este comportamiendo es detectado como malicioso.

https://www.virustotal.com/gui/file/25e60c67ac1c177cfa60eb9637ffb4b27dfbf247a5ce00b66c27eb3c3a7882a5/detection

Lo que subí a virustotal, es un hola_mundo.exe pasado por el crypter, es decir el nuevo exe generado a partir del hola_mundo.exe que se encarga de descifrar su binario y correrlo en memoria.

Conoceis alguna forma simple de evitar estas detecciones?

Aquí el código (del hola_mundo.exe compilado) generado antes de compilarlo. Este es el que subí a virustotal una vez compilado:
https://gist.github.com/StringManolo/6a3f7205e8cc7f075fcfb177bc9728f3

Adjunto también el .exe compilado:
https://github.com/StringManolo/share/raw/master/hello_world.exe
md5sum 058e321a21469b6fd3983f143b8af787
sha256sum 25e60c67ac1c177cfa60eb9637ffb4b27dfbf247a5ce00b66c27eb3c3a7882a5
7  Programación / Programación C/C++ / fread modifica algunos bytes tratando de volcar parte de un archivo en otro en: 9 Agosto 2021, 23:39 pm
Estoy haciendo un cifrado CBC y añado 1024 bytes generados de forma pseudoaleatoria al final del archivo que el usuario eliga cifrar. Por motivos de debug, estos 1024 bytes a parte de añadirlos al archivo, también creo un archivo llamado lastIV.txt con estos 1024 bytes.

Estoy programando la parte que descifra y el primer paso que estoy haciendo es obtener esos últimos 1024 bytes del final del archivo cifrado que corresponden al IV generado aleatoriamente. Para ver el resultado, escribo estos 1024 bytes en un archivo externo al que llamo extractedIV.txt

Al comparar ambos archivos, que deberían ser exactamente iguales, algunos bytes no coinciden y no tengo ni idea de porque ambos archivos no son iguales.

Aquí adjunto sus hex creados con xxd:

lastIV.txt
Código:
00000000: 5dcf c46c d3d7 561f 5b23 2c8c d252 c5c9  ]..l..V.[#,..R..
00000010: 8cf5 8070 706e df2b 2fe8 5d2b f3ff f2d8  ...ppn.+/.]+....
00000020: bd7e 8c99 edc4 a87a 26f1 077f 5d2f 132b  .~.....z&...]/.+
00000030: 2b83 1319 4e76 0e0f 0822 0d9b f686 071d  +...Nv..."......
00000040: 0ea2 b106 5cf6 1401 48a8 a95e f9b7 2ade  ....\...H..^..*.
00000050: 194e 5e80 c744 1fac 81c3 af2b ae30 2ba9  .N^..D.....+.0+.
00000060: 3f56 7b6c c413 e4af c24b 2cc4 001e b74f  ?V{l.....K,....O
00000070: f1a2 1a2b 8881 20fc b41f 12bd 14e0 9017  ...+.. .........
00000080: d8ee 866e cea9 6759 36a6 6c7d c55c b389  ...n..gY6.l}.\..
00000090: ae80 d81f 2c2b 8049 826c b9df 071b d5cd  ....,+.I.l......
000000a0: 943f acd7 0f20 4f13 1956 5c23 0b89 81c4  .?... O..V\#....
000000b0: 95e2 f3f2 7b90 f174 bdc9 0df4 ec81 6ea9  ....{..t......n.
000000c0: 132a 5e42 93e0 0d5e a4ca 13ec d013 63dc  .*^B...^......c.
000000d0: a218 5dca c54e 2ea9 0607 d53c b022 2781  ..]..N.....<."'.
000000e0: 0b7e 7142 135b de22 c5de df6d 825d 755c  .~qB.[."...m.]u\
000000f0: 6c81 1a53 6c1b 2e2b d32a fdd0 0bd6 d629  l..Sl..+.*.....)
00000100: 816e 5780 4e0b bde1 13c9 1159 4950 5c88  .nW.N......YIP\.
00000110: 927d 235c c9e8 e83c 0b9e 7fbd 959f 830d  .}#\...<........
00000120: 3b8c d7ca d7ef c3a2 2e8e ff5e dae2 f494  ;..........^....
00000130: 9fbd 5be1 a65d abe8 d8d5 862d 42b7 0ba9  ..[..].....-B...
00000140: e6ed 3ccc 2ca8 30f2 a950 883b 6722 225d  ..<.,.0..P.;g""]
00000150: 3c5c 1907 f2f7 9ab7 01b3 2cd5 98da 4080  <\........,...@.
00000160: 2319 9859 1a1a 22e8 2f21 f5c2 363d c918  #..Y.."./!..6=..
00000170: 9990 e842 ef1b efab 5e3d a2bd 2b1f 2b2a  ...B....^=..+.+*
00000180: 922f 80f5 4b36 e636 aba6 5d17 c375 8095  ./..K6.6..]..u..
00000190: 8de8 e813 aef4 ce04 33d8 f221 e8c5 d801  ........3..!....
000001a0: 93b7 ed1b 9a95 bf3d b72b 08da a4bf b165  .......=.+.....e
000001b0: bd71 c77d ee2b a853 79c0 9e52 2092 c5d8  .q.}.+.Sy..R ...
000001c0: 19e8 4052 1fde 83a1 4e8c 30b3 e619 361e  ..@R....N.0...6.
000001d0: 6cd0 9248 13d8 7bae 9536 5d44 d5e4 131b  l..H..{..6]D....
000001e0: 8c40 49f3 c38d 5d26 c3ec f790 131f f95b  .@I...]&.......[
000001f0: 635c e679 75f3 42e8 a41e 52b4 8852 2bfd  c\.yu.B...R..R+.
00000200: 7a87 d759 f43d c988 537d 6380 cfa4 b7f4  z..Y.=..S}c.....
00000210: b41b ecc7 ccfd 825c e46e 6eb4 e4c9 e83d  .......\.nn....=
00000220: 2ad1 f2a2 1fd7 7df1 843f 01f1 9664 185c  *.....}..?...d.\
00000230: 0000 0000 0000 0000 8776 ec75 5ba2 4052  .........v.u[.@R
00000240: 0004 0000 0000 0000 2010 61f9 7c00 0000  ........ .a.|...
00000250: 0000 0000 0000 0000 2010 61f9 7c00 0000  ........ .a.|...
00000260: 0010 0000 0000 0000 0010 0000 0000 0000  ................
00000270: d0d0 53d5 7f00 0000 5453 55f9 7c00 0000  ..S.....TSU.|...
00000280: 4841 01f9 7c00 0000 5417 2ce1 2c13 3c04  HA..|...T.,.,.<.
00000290: 90d1 53d5 7f00 0000 54da 5cf9 7c00 0000  ..S.....T.\.|...
000002a0: 0d17 da1a 2220 1f18 47b3 0000 0000 0000  ...." ..G.......
000002b0: 9fcc 1400 0000 0000 8081 0000 0100 0000  ................
000002c0: 8f27 0000 8f27 0000 0000 0000 0000 0000  .'...'..........
000002d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000002e0: 0010 0000 0000 0000 0000 0000 0000 0000  ................
000002f0: 3a9e 1161 0000 0000 0092 fe1e 0000 0000  :..a............
00000300: 3a9e 1161 0000 0000 0092 fe1e 0000 0000  :..a............
00000310: 3a9e 1161 0000 0000 0092 fe1e 0000 0000  :..a............
00000320: 0000 0000 0000 0000 843f 01f1 9664 185c  .........?...d.\
00000330: 40ce 53d5 7f00 0000 0100 0000 0000 0000  @.S.............
00000340: 20d2 53d5 7f00 0000 4841 01f9 7c00 0000   .S.....HA..|...
00000350: b0d1 53d5 7f00 0000 08f4 5cf9 7c00 0000  ..S.......\.|...
00000360: 4841 01f9 7c00 0000 0004 0000 0004 0000  HA..|...........
00000370: 10d2 53d5 7f00 0000 28d3 5cf9 7c00 0000  ..S.....(.\.|...
00000380: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000390: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003a0: 0004 0000 0000 0000 2010 61f9 7c00 0000  ........ .a.|...
000003b0: 40ce 53d5 7f00 0000 0100 0000 0000 0000  @.S.............
000003c0: 0004 0000 0000 0000 4841 01f9 7c00 0000  ........HA..|...
000003d0: 80d2 53d5 7f00 0000 f410 5ef9 7c00 0000  ..S.......^.|...
000003e0: 38d2 53d5 7f00 0000 0100 0000 7c00 0000  8.S.........|...
000003f0: 0004 0000 0000 0000 40ce 53d5 7f00 0000  ........@.S.....

extractedIV.txt
Código:
00000000: 5dcf c46c d3d7 561f 5b23 2c8c d252 c5c9  ]..l..V.[#,..R..
00000010: 8cf5 8070 706e df2b 2fe8 5d2b f3ff f2d8  ...ppn.+/.]+....
00000020: bd7e 8c99 edc4 a87a 26f1 077f 5d2f 132b  .~.....z&...]/.+
00000030: 2b83 1319 4e76 0e0f 0822 0d9b f686 071d  +...Nv..."......
00000040: 0ea2 b106 5cf6 1401 48a8 a95e f9b7 2ade  ....\...H..^..*.
00000050: 194e 5e80 c744 1fac 81c3 af2b ae30 2ba9  .N^..D.....+.0+.
00000060: 3f56 7b6c c413 e4af c24b 2cc4 001e b74f  ?V{l.....K,....O
00000070: f1a2 1a2b 8881 20fc b41f 12bd 14e0 9017  ...+.. .........
00000080: d8ee 866e cea9 6759 36a6 6c7d c55c b389  ...n..gY6.l}.\..
00000090: ae80 d81f 2c2b 8049 826c b9df 071b d5cd  ....,+.I.l......
000000a0: 943f acd7 0f20 4f13 1956 5c23 0b89 81c4  .?... O..V\#....
000000b0: 95e2 f3f2 7b90 f174 bdc9 0df4 ec81 6ea9  ....{..t......n.
000000c0: 132a 5e42 93e0 0d5e a4ca 13ec d013 63dc  .*^B...^......c.
000000d0: a218 5dca c54e 2ea9 0607 d53c b022 2781  ..]..N.....<."'.
000000e0: 0b7e 7142 135b de22 c5de df6d 825d 755c  .~qB.[."...m.]u\
000000f0: 6c81 1a53 6c1b 2e2b d32a fdd0 0bd6 d629  l..Sl..+.*.....)
00000100: 816e 5780 4e0b bde1 13c9 1159 4950 5c88  .nW.N......YIP\.
00000110: 927d 235c c9e8 e83c 0b9e 7fbd 959f 830d  .}#\...<........
00000120: 3b8c d7ca d7ef c3a2 2e8e ff5e dae2 f494  ;..........^....
00000130: 9fbd 5be1 a65d abe8 d8d5 862d 42b7 0ba9  ..[..].....-B...
00000140: e6ed 3ccc 2ca8 30f2 a950 883b 6722 225d  ..<.,.0..P.;g""]
00000150: 3c5c 1907 f2f7 9ab7 01b3 2cd5 98da 4080  <\........,...@.
00000160: 2319 9859 1a1a 22e8 2f21 f5c2 363d c918  #..Y.."./!..6=..
00000170: 9990 e842 ef1b efab 5e3d a2bd 2b1f 2b2a  ...B....^=..+.+*
00000180: 922f 80f5 4b36 e636 aba6 5d17 c375 8095  ./..K6.6..]..u..
00000190: 8de8 e813 aef4 ce04 33d8 f221 e8c5 d801  ........3..!....
000001a0: 93b7 ed1b 9a95 bf3d b72b 08da a4bf b165  .......=.+.....e
000001b0: bd71 c77d ee2b a853 79c0 9e52 2092 c5d8  .q.}.+.Sy..R ...
000001c0: 19e8 4052 1fde 83a1 4e8c 30b3 e619 361e  ..@R....N.0...6.
000001d0: 6cd0 9248 13d8 7bae 9536 5d44 d5e4 131b  l..H..{..6]D....
000001e0: 8c40 49f3 c38d 5d26 c3ec f790 131f f95b  .@I...]&.......[
000001f0: 635c e679 75f3 42e8 a41e 52b4 8852 2bfd  c\.yu.B...R..R+.
00000200: 7a87 d759 f43d c988 537d 6380 cfa4 b7f4  z..Y.=..S}c.....
00000210: b41b ecc7 ccfd 825c e46e 6eb4 e4c9 e83d  .......\.nn....=
00000220: 2ad1 f2a2 1fd7 7df1 843f 01f1 9664 185c  *.....}..?...d.\
00000230: 0000 0000 0000 0000 8776 ec75 5ba2 4052  .........v.u[.@R
00000240: 0004 0000 0000 0000 2010 61f9 7c00 0000  ........ .a.|...
00000250: 0000 0000 0000 0000 2010 61f9 7c00 0000  ........ .a.|...
00000260: 0010 0000 0000 0000 0010 0000 0000 0000  ................
00000270: d0d0 53d5 7f00 0000 5453 55f9 7c00 0000  ..S.....TSU.|...
00000280: b040 01f9 7c00 0000 5417 2ce1 2c13 3c04  .@..|...T.,.,.<.
00000290: 90d1 53d5 7f00 0000 54da 5cf9 7c00 0000  ..S.....T.\.|...
000002a0: 0d17 da1a 2220 1f18 47b3 0000 0000 0000  ...." ..G.......
000002b0: 3b78 0c00 0000 0000 8081 0000 0100 0000  ;x..............
000002c0: 8f27 0000 8f27 0000 0000 0000 0000 0000  .'...'..........
000002d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000002e0: 0010 0000 0000 0000 0000 0000 0000 0000  ................
000002f0: ed8d 1161 0000 0000 00a0 2526 0000 0000  ...a......%&....
00000300: 3a9e 1161 0000 0000 0092 fe1e 0000 0000  :..a............
00000310: 3a9e 1161 0000 0000 0092 fe1e 0000 0000  :..a............
00000320: 0000 0000 0000 0000 843f 01f1 9664 185c  .........?...d.\
00000330: 2ce7 53d5 7f00 0000 0100 0000 0000 0000  ,.S.............
00000340: 20d2 53d5 7f00 0000 b040 01f9 7c00 0000   .S......@..|...
00000350: b0d1 53d5 7f00 0000 08f4 5cf9 7c00 0000  ..S.......\.|...
00000360: b040 01f9 7c00 0000 ee39 806d 2bd7 3d50  .@..|....9.m+.=P
00000370: 10d2 53d5 7f00 0000 843f 01f1 9664 185c  ..S......?...d.\
00000380: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000390: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003a0: 0004 0000 0000 0000 2010 61f9 7c00 0000  ........ .a.|...
000003b0: 40ce 53d5 7f00 0000 0100 0000 0000 0000  @.S.............
000003c0: 0004 0000 0000 0000 b040 01f9 7c00 0000  .........@..|...
000003d0: 80d2 53d5 7f00 0000 f410 5ef9 7c00 0000  ..S.......^.|...
000003e0: 38d2 53d5 7f00 0000 0100 0000 0000 0000  8.S.............
000003f0: 0004 0000 0000 0000 40ce 53d5 7f00 0000  ........@.S.....

Aquí el código:
Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<time.h>
  4.  
  5. // add operation between 2 buffers
  6. void addBuffers(char * buf1, char * buf2, int bufSize) {
  7.  for(int i = 0; i < bufSize; ++i) {
  8.    buf1[i] = (buf1[i] + buf2[i]);
  9.  }
  10. }
  11.  
  12. // substract operation between 2 buffers
  13. void substractBuffers(char * buf1, char * buf2, int bufSize) {
  14.  for(int i = 0; i < bufSize; ++i) {
  15.    buf1[i] = (buf1[i] - buf2[i]);
  16.  }
  17. }
  18.  
  19. // make key match the block size
  20. void securizeKey(char * keyBuf, char * key, int keySize, int chunkSize) {
  21.  for (int i = 0, j = 0; i < chunkSize; ++i, ++j) {
  22.    if (j > keySize) {
  23.      j = 0;
  24.    }
  25.    keyBuf[i] = key[j];
  26.  }
  27. }
  28.  
  29. // generate pseudorandom buffer
  30. char *allocate_random_heap_buffer(size_t size) {
  31.  time_t current_time = time(NULL);
  32.  srandom((unsigned int) current_time);
  33.  char* allocatedMemory = (char *) malloc(size);
  34.  
  35.  for (int bufferIndex = 0; bufferIndex < size; bufferIndex++) {
  36.    uint8_t randomNumber = (uint8_t) random();
  37.    allocatedMemory[bufferIndex] = randomNumber;
  38.  }
  39.  
  40.  return allocatedMemory;
  41. }
  42.  
  43. // generate a pseudorandom IV
  44. void generateIV(char * ivBuf, int chunkSize) {
  45.  char * random = allocate_random_heap_buffer(chunkSize);
  46.  for (int i = 0; i < chunkSize; ++i) {
  47.    if (random[i] < chunkSize) {
  48.      ivBuf[i] = random[random[i]];
  49.    } else {
  50.      ivBuf[i] = random[i];
  51.    }
  52.  }
  53. }
  54.  
  55. char * GENERATED_IV;
  56. // block cipher encryption
  57. void cipherBlock(char * bufferBlock, char * bufferBlock2, char * key, int blockSize, int round) {
  58.  if (round == 1) { // add IV to first block
  59.    char IV[blockSize];
  60.    generateIV(IV, blockSize);
  61.    addBuffers(bufferBlock, IV, blockSize);
  62.    GENERATED_IV = IV;
  63.  } else { // add Last Block to Current Block
  64.    addBuffers(bufferBlock, bufferBlock2, blockSize);
  65.    addBuffers(bufferBlock, key, blockSize);
  66.  }
  67. }
  68.  
  69.  
  70. // reverse
  71.  
  72.  
  73. int main(int argc, char *argv[]) {
  74.  /*** Fetch CLI Arguments */
  75.  char * filename; int filenameSet = 0; // file to work on
  76.  char * mode;     int modeSet = 0; // encrypt or decrypt
  77.  char * key;      int keySet = 0; // simmetric key
  78.  char * output;   int outputSet = 0; // file to output results on
  79.  for(int i = 0; i < argc; ++i) {
  80.    // -f or --file
  81.    if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--file") == 0) {
  82.      filename = argv[i + 1];
  83.      filenameSet = 1;
  84.    // -m or --mode
  85.    } else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mode") == 0) {
  86.      mode = argv[i + 1];
  87.      modeSet = 1;
  88.    // -k or --key
  89.    } else if (strcmp(argv[i], "-k") == 0 || strcmp(argv[i], "--key") == 0) {
  90.      key = argv[i + 1];
  91.      keySet = 1;
  92.    } else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) {
  93.      output = argv[i + 1];
  94.      outputSet = 1;
  95.    }
  96.  }
  97.  
  98.  // Check if mandatory arguments are set
  99.  if (filenameSet != 1) {
  100.    printf("Missing filename argument, use -f ./myFile");
  101.    return 0;
  102.  }
  103.  
  104.  if (modeSet != 1) {
  105.    printf("Please select a mode, use -m cipher or use -m reverse");
  106.    return 0;
  107.  }
  108.  
  109.  if (keySet != 1) {
  110.    printf("Missing key argument, use -k mySecretKey");
  111.    return 0;
  112.  }
  113.  
  114.  if (outputSet != 1) {
  115.    printf("Missing output argument, use -o ./newFile");
  116.    return 0;
  117.  }
  118.  /* Fetch CLI Arguments ***/
  119.  
  120.  
  121.  #define BLOCK_SIZE 1024
  122.  const int keySize = strlen(key);
  123.  char keyBuf[BLOCK_SIZE];
  124.  securizeKey(keyBuf, key, keySize, BLOCK_SIZE);
  125.  
  126.  
  127.  if (strcmp(mode, "cipher") == 0) { // user selected encryption mode
  128.    char buf[BLOCK_SIZE];
  129.    char lastBuf[BLOCK_SIZE];
  130.    FILE *file;
  131.    size_t nread;
  132.  
  133.    file = fopen(filename, "r");
  134.    FILE * encrypted = fopen(output, "w"); // file to output the encrypted file
  135.    if (file) {
  136.      int i = 0;
  137.      while ((nread = fread(buf, 1, sizeof buf, file)) > 0) {
  138.        cipherBlock(buf, lastBuf, keyBuf, BLOCK_SIZE, ++i);
  139.        memcpy(lastBuf, buf, BLOCK_SIZE);
  140.        fwrite(buf, 1, nread, encrypted);
  141.      }
  142.      fwrite(GENERATED_IV, 1, BLOCK_SIZE, encrypted);
  143.  
  144.      FILE * lastIV = fopen("./lastIV.txt", "w");
  145.      fwrite(GENERATED_IV, 1, BLOCK_SIZE, lastIV); // debug IV
  146.  
  147.      if (ferror(file)) {
  148.        // deal with error
  149.      }
  150.      fclose(file);
  151.    }
  152.  } else if (strcmp(mode, "reverse") == 0) {
  153.    /* TODO: READ REVERSE IN CHUNKS */
  154.    char buf[BLOCK_SIZE];
  155.    char lastBuf[BLOCK_SIZE];
  156.    FILE *file;
  157.    size_t nread;
  158.  
  159.    file = fopen(filename, "r");
  160.    FILE * decrypted = fopen(output, "w"); // file to output the decrypted file
  161.  
  162.    if (file) {
  163.      int i = 0;
  164.      fseek(file, 0, SEEK_END);
  165.      int sz = ftell(file); // file size
  166.      char IV[BLOCK_SIZE];
  167.  
  168.      char aux[BLOCK_SIZE];
  169.  
  170.  
  171.      for (int j = sz - BLOCK_SIZE; /* j > 0 */; j -= BLOCK_SIZE, ++i) {
  172.        fseek(file, j, SEEK_SET);
  173. fread(aux, 1, BLOCK_SIZE, file);
  174.        if (i == 0) {
  175.          memcpy(IV, aux, BLOCK_SIZE);
  176.          FILE * extractedIV = fopen("./extractedIV.txt", "w");
  177.          fwrite(IV, 1, BLOCK_SIZE, extractedIV); // debug IV
  178.          fclose(extractedIV);
  179.          return 0;
  180.        }
  181.  
  182. if (j <= 0) {
  183.          break;
  184. }
  185.      }
  186.      fclose(file);
  187.    }
  188.  
  189.  } else {
  190.    printf("Select -m cipher or -m reverse");
  191.    return 0;
  192.  }
  193.  return 0;
  194. }

PD: Adjunto output de radiff2 de los bytes que son transformados:
Código:
0x00000280 4841 => b040 0x00000280
0x000002b0 9fcc14 => 3b780c 0x000002b0
0x000002f0 3a9e => ed8d 0x000002f0
0x000002f9 92fe1e => a02526 0x000002f9
0x00000330 40ce => 2ce7 0x00000330
0x00000348 4841 => b040 0x00000348
0x00000360 4841 => b040 0x00000360
0x00000368 0004000000040000 => ee39806d2bd73d50 0x00000368
0x00000378 28d35cf97c000000 => 843f01f19664185c 0x00000378
0x000003c8 4841 => b040 0x000003c8
0x000003ec 7c => 00 0x000003ec
8  Programación / Programación C/C++ / Asignar tipo a variables en C++ en: 9 Abril 2021, 15:05 pm
Estoy generando código C++ a partir de otro código de un lenguaje que estoy desarrollando. La funciones las estoy implementando rollo bash.

Sabeis como puedo declarar los argumentos? Estoy forzado a hacer type inference en el preprocesador/compilador y declarar un template por cada llamada que utilice un tipo distinto (la única solución que se me ocurrió hasta el momento) o conoceis alguna alternativa más sencilla?

CÓDIGO A TRANSPILAR/COMPILAR:
Código
  1. x = "Hello World";
  2. showHelloWorld() {
  3.  out($1);
  4.  return 6 * 7;
  5. }
  6.  
  7. showHelloWorld(x);
  8. x = 8;


CÓDIGO QUE GENERO:
Código
  1. #include <string>
  2.  
  3. using namespace std;
  4.  
  5. auto showHelloWorld($1);
  6.  
  7. int main() {
  8.  auto x = "Hello World" ;
  9.  showHelloWorld ( x ) ;
  10.  x = 8 ;
  11.  
  12.  return 0;
  13. }
  14.  
  15. auto showHelloWorld($1) {
  16.  cout << $1 << endl;
  17.  return 6 * 7 ;
  18. }


Lo que necesito hacer es asignarle un tipo (para que no de error) a los $1, $2, $3... y al $. Este último es un array con todos los argumentos dentro como en bash.

Hay que tener en cuenta que cada llamada a la función puede tener el mismo argumento con distinto tipo, ejemplo:
Código
  1. imprimir($1) {
  2.  cout << $1 << endl;
  3. }
  4.  
  5. int main() {
  6.  imprimir("hola");
  7.  imprimir(7);
  8.  // ...
  9. }

Se os ocurre alguna solución sencilla?
9  Foros Generales / Sugerencias y dudas sobre el Foro / Duda a cerca de la norma de no resolver tareas a los usuarios del foro. en: 5 Abril 2021, 14:57 pm
Hola, quería exponer una duda a cerca de una respuesta que hice a un usuario en el foro de C/C++.
En concreto este es el mensaje al que hago referencia: https://foro.elhacker.net/programacion_cc/crash_en_la_consola-t509690.0.html;msg2239804#msg2239804

Mi duda es a cerca de la norma de no resolver tareas a los usuarios del foro. E publicado una respuesta en la que incluyo un ejemplo completo del programa que necesita realizar a posteriori de que el usaurio ya ha conseguido dar con una solución y la ha publicado en el tema.

Mi motivación para aportar una respuesta completa a la tarea viene a coalición con lo que he expuesto en el mismo mensaje. En concreto trato de ejemplificar el uso de identación, funciones puras (lo que trata de usar el usuario que abre el tema) y proponer otra alternativa más organizada a la resolución de la tarea.

La razón de mi duda viene tras recibir un mensaje privado

No entendí cual era el problema asique respondí explicando mi motivación al publicar el código y preguntando cual era el motivo. No me convenció el argumento de la cantidad de lineas de código con respecto al usuario ya que el usuario omitió varios saltos de lineas que yo si añadí para que el código quedase mejor organizado así como el uso de más includes y funciones por mi parte en lugar de meter todo en una sola función, lo cual de por sí cada función son mínimo 4 o 5 lineas más. El prototipo, la declaracion, el return, el corchete final de la declaración y las llamadas que hago en cout, que decidí utilizar 3 llamadas independientes de cout en lugar de una sola para que el código quedase más claro

Tras lo cual:

Yo personalmente creo que mi código no es excesivo ni innecesario, asique en lugar de seguir respondiendo por privado y seguir argumentando (algo que obviamente no va a llevar a ningún lugar porque ya ambas partes hemos expuesto nuestra opinión a cerca del tema y no parece que vayamos a llegar a ningún lado) decido exponer mi duda aquí para zanjar el debate a cerca de si es correcta mi respuesta o no.
En caso de no serlo no tengo ningua objeción en que sea eliminado, modificado o lo que sea.

También me gustaría tener unas directrices claras de cuanto código es excesivo para poder seguir participando sin inclumplir las normas. O si la cantidad de código permitido en una respuesta mantiene algún tipo de relación con la cantidad de código sin identar que publica el usuario que abre el tema.

[MOD] Retirados los MP, estos no deben ser publicados en publico, al ser privados.
10  Comunicaciones / Android / Crear APKs en Termux en: 31 Marzo 2021, 04:18 am
Crear APKs en Termux
Siempre he querido programar apks (el .exe de android) directamente en Android. Tras varias búsquedas a lo largo del tiempo encontré una forma de crear apks usando comandos. Tanto Java como Kotlin son lenguajes que no me entusiasman precisamente asique he desarrollado un script en javascript y un par de repos para poder construir la apk a partir de una url o una carpeta con archivos html, css, js y demás de tal forma que no tengas que tocar ni una sola linea de código de java, kotlin, xml, etc. No es nada complejo, solo tienes que correr 2 comandos.

Instalación
Mi script utiliza unos cuantos paquetes de Termux:
  Quickjs
  Git
  Aapt
  Apksigner
  Dx
  Ecj
  Curl
  buildAPKs

Hice un commando para que simplemente lo copies y pegues, te deja todo listo. Si acabas de descargarte termux, corre termux-setup-storage antes de nada. Si ya tenías acceso a la carpeta storage no hace falta.

Aquí el comando:
Código:
yes | pkg install quickjs git aapt apksigner dx ecj curl; curl -O https://raw.githubusercontent.com/BuildAPKs/buildAPKs/master/setup.buildAPKs.bash && yes | bash setup.buildAPKs.bash && cp ~/buildAPKs/scripts/bash/build/build.one.bash ~/../usr/bin/ && chmod +775 ~/../usr/bin/build.one.bash; git clone https://github.com/StringManolo/APKGenerator && cd APKGenerator
La instalación va a crear un par de apks para comprobar que todo funciona. Si te pide permisos para poder levantar termux en segundo plano, te recomiendo aceptarlo ya que te puede ser útil en el futuro cuando hagas o corras algún programa que lo necesita. Cuando finalice la instalación ya podrás crear tu app de Android utilizando APKGenerator

Creando la apk
El método de creación es muy sencillo. Tienes 2 comandos para elegir la fuente que se utilizará para generar la app, desde una url o desde una carpeta con tu index.html, estilos.css, codigo.js, etc.
Para crear desde una url, corre el comando
Código:
qjs --std APKGenerator.js -u https://example.com -n com.example.miApp -t Example
Para crear desde carpeta pon
Código:
qjs --std APKGenerator.js -a myAssets -n com.example.miApp -t Example
En este caso se usará la carpeta myAssets que ya se descargó con un index.html, un archivo css y uno javascript para que no tengas que crearlos a mano en caso de que vayas a programar una web de 0. El único requisito es que el archivo se llame index.html.
La única diferencia entre ambos comandos es el primer agumento, que indica si usar una url o una carpeta.

El argumento -n es el nombre del paquete. Es una convención usar un dominio si tienes uno. Esto sirve para que Android sepa diferenciar entre apps que se llamen igual. Puedes poner el nombre que quieras en caso de no tener un dominio.

El argumento -t es el título de la app. Será el nombre que vea el usuario al instalar la app.

Creando desde url
Cuando creas la apk desde una url, se crea un navegador sin barra de direcciones (webview) que va a visitar esa url al abrirla. Todas las peticiones realizadas por el webview incluyen la cabecera HTTP X-Request-With: nombre.del.paquete asique puedes utilizar esta información para servir una versión especial de tu sitio web cuando se te solicite al servidor la web con esta cabecera. Obviamente necesitas internet para que funciones la app. En futuras versiones añadiré caché al webview y un script para cachear tu sitio, así podrás cargar tu sitio web sin conexión a internet.

Creando desde carpeta
Cuando creas desde carpeta esta es añadida a la apk por lo que funciona totalmente offline. Tendrás que manejar tu las actualizaciones de la app para que el usuario pueda actualizar la web. También puedes añadir un script online a la web para encargarte de ello. Recomendado también que utilices la push notifications api de javascript si provees otra forma de actualizarla.

Cambiando archivos de la apk
Cuando realices cualquier tipo de cambio tendrás que generar una nueva apk. Para ello ve a la carpeta de tu proyecto por ejemplo com.example.miApp/src/main y corre el comando build.one.bash
La apk generada se incluye en la carpeta del proyecto (para debug con herramientas si lo necesitas) y en la carpeta Download/builtAPKs para instalar/distribuir. Puedes visitar el repositorio del proyecto en github si desear ver el código, reportar algún fallo, solicitar alguna característica o contribuir en el proyecto. APKGenerator
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 19
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines