Descripción de los conceptos básicos de la conversión de cifrado AES

Buen dia, Habr! Hace unos 3 meses, el desarrollador de la interfaz de usuario entrevistó y la primera pregunta que me hicieron: "¿Qué es AES?" Bueno, como si tuviera una idea amorfa sobre el cifrado simétrico de bloques de AES, incluso se usó en uno de los proyectos para cifrar datos personales. Pero para conocer el algoritmo rijndael y aún poder implementarlo en javascript, para mí en ese momento me pareció una tarea difícil. ¡Pero! Fui desafiado y aceptado.



¡Ve al aparejo!

Como base, tomé la especificación FIPS197 AES del 26 de noviembre de 2011.

En el campo de TI, algunos de los algoritmos de cifrado más famosos son:

  • simétrico
  • asimétrico

Los algoritmos simétricos son aquellos algoritmos que tienen una clave secreta para el cifrado y la misma clave para el descifrado. La ventaja de este algoritmo es la velocidad de cifrado. Desventajas: la necesidad de un canal seguro para transmitir esta clave para el descifrado.

A su vez, los algoritmos simétricos se dividen en dos tipos:

  • bloque
  • transmisión

Los bloques tienen la capacidad de cifrar datos en bloques, es decir, un número finito predeterminado de bytes. Esto implica la posibilidad de paralelizar el cifrado de bloques, es decir, cifrar grandes cantidades de datos al mismo tiempo, al tiempo que se reduce el recurso de tiempo.

Secuencia de cifrado de caracteres por caracteres.

Las ventajas de los algoritmos asimétricos son su almacenamiento seguro de claves. Asimétrico: aquellos algoritmos que tienen dos claves:

  • Llave pública
  • llave privada

publicKey es la clave para el cifrado. No está sujeto a descifrado, lo que significa que no hay necesidad de transferirlo.
privateKey : la clave para descifrar.

Las desventajas de los algoritmos asimétricos son su rendimiento de cifrado relativamente lento.

Rijndael es un algoritmo de cifrado de bloque simétrico con la capacidad de redimensionar bloques y claves privadas de 128 a 256 bits con una diferencia de 32 bits. Utiliza transformaciones de sustitución lineal y consta de 10, 12 o 14 rondas dependiendo de la longitud de la clave.
AES - rijndael con una clave de 128 bits y un bloque de datos de 16 bytes.

Presumiblemente está familiarizado con la teoría de los siguientes términos:

  • sistema de numeración binaria
  • sistema de numeración decimal
  • pedacitos
  • bytes
  • XOR (^)

Si no, entonces no importa. Lea mi artículo "Procesamiento de imágenes ReactJS - NodeJS» o eche un vistazo a los ejemplos snipettov reactjs.su

Conceptos matemáticos en rijndael:


  • El campo GF (2⁸) es un número finito de elementos, cuyo resultado es el enésimo grado natural de un número primo. Dentro del marco de GF (2⁸), se realizan operaciones arbitrarias de suma, resta, producto, división. El campo GF (2⁸) es definitivo.
  • . Rijndael [00000000₂; 11111111₂]. , x. , , :

    a(x)=a₇x⁷ +a₆x⁶ +a₅x⁵ +a₄x⁴ +a₃x³ +a₂x² +a₁x +a₀x;

    , a₇, a₆, a₅, a₄, a₃, a₂, a₁, a₀ {0, 1}, :
    87 = 01010111 ( );
    : x⁶ + x⁴ + x² + x + 1;
  • . , , 1 . rijndael m(x):
    m(x)= x⁸ + x⁴ + x³ + x + 1;
  • . XOR, : 1 ^ 1 = 0 ^ 0 = 0; 1 ^ 0 = 0 ^ 1 = 1, :

    , a₇, a₆, a₅, a₄, a₃, a₂, a₁, a₀;
    B, b₇, b₆, b₅, b₄, b₃, b₂, b₁, b₀;

    A = 87 = 01010111; B = 131 = 10000011;
    A ^ B = a₇, a₆, a₅, a₄, a₃, a₂, a₁, a₀ ^ b₇, b₆, b₅, b₄, b₃, b₂, b₁, b₀ = 11010100;
  • . GF(2⁸) ( | -x | = x ) 8, :

    87 x 131 :
    (x⁶ + x⁴ + x² + x + 1)(x⁷ + x + 1) = x¹³ + x¹¹ + x⁹ + x⁸ + x⁷ + x⁷ + x⁵ + x³ + x² + x + x⁶ + x⁴ + x² + x + 1.
    . (.4):

    x⁷ + x⁷ = x⁷(1 + 1) = x⁷(1 ^ 1) = x⁷0 = 0;
    (x⁶ + x⁴ + x² + x + 1)(x⁷ + x + 1) = x¹³ + x¹¹ + x⁹ + x⁸ + x⁶ + x⁵ + x⁴ + x³ + 1.

    m(x) = x⁸ + x⁴ + x³ + x + 1 ( ), rijndael , 8, . . , . :

    (x⁶ + x⁴ + x² + x + 1)(x⁷ + x + 1)/(x⁸ + x⁴ + x³ + x + 1) =
    (x¹³ + x¹¹ + x⁹ + x⁸ + x⁶ + x⁵ + x⁴ + x³ + 1)/(x⁸ + x⁴ + x³ + x + 1) = |Result| = x⁷ + x⁶ + 1


:


  1. keyExpansion() — ;
  2. addRoundKey() — ;
  3. subBytes() — state;
  4. shiftRows() — state;
  5. mixColumns() — state;
  6. invMixColumns() — mixColumns;
  7. invShiftRows() — shiftRows;
  8. invSubBytes() — subBytes;

AES :


  1. state
    - . [0; 255] ( ASCII Unicode). n- 16 . state ( 4 = [ [], [], [], [] ] ), 16 , 16 :

  2. keyExpansion();
    AES, state. . XOR Rcon.

    Rcon — XOR. keyExpansion() XOR’ Rcon . — 11. 10 .

    let rCon = [
      [ 0x00, 0x00, 0x00, 0x00 ],
      [ 0x01, 0x00, 0x00, 0x00 ],
      [ 0x02, 0x00, 0x00, 0x00 ],
      [ 0x04, 0x00, 0x00, 0x00 ],
      [ 0x08, 0x00, 0x00, 0x00 ],
      [ 0x10, 0x00, 0x00, 0x00 ],
      [ 0x20, 0x00, 0x00, 0x00 ],
      [ 0x40, 0x00, 0x00, 0x00 ],
      [ 0x80, 0x00, 0x00, 0x00 ],
      [ 0x1b, 0x00, 0x00, 0x00 ],
      [ 0x36, 0x00, 0x00, 0x00 ],
    ];
    
  3. addRoundKey();

    state , . addRoundKey XOR’ state, . ’XOR’ state , :




  4. 10 , 10 . 9 4 :

    • subBytes();
    • shiftRows();
    • mixColumns();
    • addRoundKey();

    10- :

    • subBytes();
    • shiftRows();
    • addRoundKey();

  5. subBytes();

    state S-box:



    State hex , : 01010011 -> 0101 | 0011 -> 53h



    53h edh

    S-box
    const sBox = [
      0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
      0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
      0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
      0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
      0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
      0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
      0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
      0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
      0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
      0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
      0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
      0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
      0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
      0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
      0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
      0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
    ];
    


  6. shiftRows();

    3- :


  7. mixColumns();

    . a(x) = {03}x³ + {01}x² + {01}x + {02}. state a(x). :







AES :


  1. keyExpansion();


  2. 10 , .

    9 4 , , :

    • addRoundKey();
    • invMixColumns();
    • invShiftRows();
    • invSubBytes();

    10-:

    • addRoundKey();
    • invShiftRows();
    • invSubBytes();

  3. addRoundKey();

    , Rcon
  4. invMixColumns ();

    La función invMixColumns realiza la operación de multiplicación inversa multiplicativa de acuerdo con las reglas de multiplicación del algoritmo por la función constante a⁻¹ (x) de una columna de estado particular:




  5. invShiftRows ();

    Transformación inversa shiftRows () - desplazamiento cíclico a la derecha:


  6. invSubBytes ();

    SubBytes de inversión (): el reemplazo inverso de bytes de estado, que obviamente se representa en hexadecimal de acuerdo con la tabla de cuadro S inversa fija:



Bibliografía:

  1. Especificación para el AES
  2. Estándar de cifrado avanzado (AES)
  3. Polo Galois
  4. Códigos cíclicos
  5. Libro de texto para escuelas secundarias A.N. Stepanov - Curso de informática - Seguridad de los datos de información
  6. Fragmentos

All Articles