Algoritmo de cifrado DES e implementación de python

1. Introducción

        El algoritmo DES es un algoritmo de cifrado de bloques común propuesto por IBM en 1971. El algoritmo DES es un representante típico del algoritmo de cifrado de bloques. Su operación de cifrado y descifrado utilizan la misma clave secreta.

        El algoritmo DES utiliza 56+8 bits de paridad (8, 16, 24, 32, 40, 48, 56, 64) = clave de 64 bits para cifrar y descifrar datos de bloques en unidades de 64 bits.

        El algoritmo DES usa 64 bits como un grupo de cifrado de bloques, por lo que cuando la longitud del texto sin formato de entrada no cumple con el múltiplo entero de 64, debe involucrar el relleno de datos.

        El algoritmo DES divide el texto sin formato de entrada en N grupos de 64 bits y luego genera N grupos de textos cifrados de acuerdo con la operación de cifrado. Los N grupos de textos cifrados generados son el resultado final que queremos: salida de texto cifrado DES.

        Para obtener conocimientos de criptografía moderna, incluido el algoritmo DES, puede consultar el siguiente blog

El contenido de "Criptografía aplicada" en los requisitos del examen CISSP ayuda a la memoria y a las conferencias interesantes_Blog de Xiaoxiangzai-Blog de CSDN

2. Principio de cifrado DES

2.1 Reemplazo inicial

La permutación inicial es codificar y reordenar el texto sin formato M. y generar L0, R0

2.2 Generar subclave

Durante el proceso de cifrado DES, el texto sin formato M ha pasado por 16 iteraciones de operación y la longitud de datos de cada iteración es 48, por lo que necesitamos 16 juegos de claves de cifrado de 48 bits para el cifrado.

        Reemplazo de PC-1

        Reemplazo de PC-2

2.3 Proceso iterativo

función f

         La función f es el proceso de cálculo continuo de Li y Ri. Este proceso incluye cuatro partes: reemplazo de la caja E, reemplazo de la caja S, reemplazo de la caja P, verificación izquierda y derecha

2.4 Permutación inversa

2.5 Descifrado

        El proceso de descifrado es el mismo que el proceso de cifrado, pero en orden inverso.

2.6 Llenado de datos

        Cuando la longitud del texto sin formato no es un múltiplo entero de la longitud del paquete, es necesario completar algunos datos en el último paquete para formar una longitud de paquete.

La
API NoPadding o el algoritmo en sí no procesa los datos, y los datos cifrados se completan con el algoritmo acordado por las partes de cifrado. Por ejemplo, si desea cifrar y descifrar datos de cadena, puede agregar \0 o espacios y luego recortar

Antes del cifrado PKCS5Padding
: la longitud del byte de datos es 8 y el resto es M. Si m> 0, entonces compone 8 bytes y el valor del byte es de 8 m. Sección, el valor del byte es el número de bytes a se agregará, si es 0, se agregarán 8 bytes
después del descifrado: tome el último byte, el valor es m, luego elimine m bytes del final de los datos, y los datos restantes son el texto original antes del cifrado.
Si la cadena cifrada es AAA, el relleno es AAA55555; si la cadena cifrada es BBBBBB, el relleno es BBBBBB22; si la cadena cifrada es CCCCCCCC, el relleno es CCCCCCCC88888888.

PKCS7Padding
El método de llenado de PKCS7Padding es el mismo que el de PKCS5Padding. Solo el número de bytes del bloque encriptado es diferente. PKCS5Padding define claramente que el bloque de cifrado es de 8 bytes, y el bloque de cifrado de PKCS7Padding puede estar entre 1 y 255.

2.7 Modo de cifrado

Modo libro de códigos electrónico (ECB)

        Propósito general: cifrar pequeñas cantidades de datos, como claves secretas y valores de PIN

Modo Cipher Block Chaining (Cipher Block Chaining, CBC)

         Propósito general: Cifrado de datos grandes

Modo de retroalimentación de cifrado (CFB)

        Propósito general: encriptación de datos más pequeños, encriptación de cada bit individualmente

Modo de retroalimentación de salida (OFB)

        Características: menos probabilidades de tener errores de expansión que OFB

Modo Count (CountER, CTR).

        Características: contador IV, paralelo

referencia

Este blog explica los principios del cifrado DES de una manera fácil de entender y vale la pena leerlo.

Principio del algoritmo de cifrado DES e implementación del código_des algoritmo de cifrado code_better_hui's blog-CSDN blog

3. Implementación del código

3.1 Códigos de cifrado y descifrado en los modos ECB y CBC

from pyDes import des, CBC, PAD_PKCS5
import binascii


def bytesToHexString(data):
    temp = []
    for i in data:
        temp.append('0x%02X' % i)
    return temp


"""
    DES-ECB 加密
    :param s: 原始字符串,密钥
    :return: 加密后字符串,16进制
    """


def des_encrypt(s, key):
    secret_key = key
    iv = secret_key
    k = des(secret_key)
    en = k.encrypt(s)
    return binascii.b2a_hex(en)


"""
    DES-ECB 解密
    :param s: 原始字符串,密钥
    :return: 解密后字符串,16进制
    """


def des_decrypt(s, key):
    secret_key = key
    iv = secret_key
    k = des(secret_key)
    en = k.decrypt(s)
    return binascii.b2a_hex(en)


"""
    DES-CBC 加密
    :param s: 原始字符串,密钥
    :return: 加密后字符串,16进制
    """


def des_cbc__encrypt(s, key, iv):
    secret_key = key

    k = des(secret_key, mode=CBC, IV=iv)
    en = k.encrypt(s)
    return binascii.b2a_hex(en)


"""
    DES-CBC 加密
    :param s: 原始字符串,密钥
    :return: 加密后字符串,16进制
    """


def des_cbc__decrypt(s, key, iv):
    secret_key = key

    k = des(secret_key, mode=CBC, IV=iv)
    en = k.decrypt(s)
    return binascii.b2a_hex(en)


if __name__ == '__main__':
    data = '1111111111111111'
    key = '1111111111111111'
    iv = '1111111111111111'  # iv 仅仅用于cbc模式,若iv设置为全0,则CBC模式的计算结果和ECB模式是一样的
    print("data:", data, "key:", key, "iv:", iv)
    print("des ecb encrypt result:", des_encrypt(bytes.fromhex(data), bytes.fromhex(key)))
    print("des ecb decrypt result:", des_decrypt(bytes.fromhex(data), bytes.fromhex(key)))
    print("des cbc encrypt result:",
          des_cbc__encrypt(bytes.fromhex(data), bytes.fromhex(key), bytes.fromhex(iv)))
    print("des cbc decrypt result:",
          des_cbc__decrypt(bytes.fromhex(data), bytes.fromhex(key), bytes.fromhex(iv)))

resultados de autodiagnóstico

data: 1111111111111111 key: 1111111111111111 iv: 1111111111111111
des ecb encrypt result: b'f40379ab9e0ec533'
des ecb decrypt result: b'237b2304c393d3ac'
des cbc encrypt result: b'82e13665b4624df5'
des cbc decrypt result: b'326a3215d282c2bd'

Process finished with exit code 0

3.2 Descodificación y codificación de código Python en un escenario de aplicación

Un conocido:

1. Utilizando el algoritmo de cifrado DES ECB, se ha obtenido la clave secreta.

2. Obtuvo "prefijo de texto sin formato" + texto cifrado", que están todos representados en hexadecimal. El texto cifrado se compone de "bits fijos de longitud fija + marca de tiempo + crc". crc usa el modo ccitt_false.

necesidad:

El prefijo del texto sin formato permanece sin cambios.Después de que DES descodifica el texto cifrado, la marca de tiempo se actualiza a la última, y ​​el crc se vuelve a calcular y luego se cifra para generar datos reenviados.

programa pitón:

import pyDes
from pyDes import des, CBC, PAD_PKCS5, ECB
import binascii
import datetime
from time import time
from binascii import unhexlify
from crcmod import mkCrcFun


# CRC16/CCITT
def crc16_ccitt(s):
    crc16 = mkCrcFun(0x11021, rev=True, initCrc=0x0000, xorOut=0x0000)
    return get_crc_value(s, crc16)


# CRC16/CCITT-FALSE
def crc16_ccitt_false(s):
    crc16 = mkCrcFun(0x11021, rev=False, initCrc=0xFFFF, xorOut=0x0000)
    return get_crc_value(s, crc16)


# CRC16/MODBUS
def crc16_modbus(s):
    crc16 = mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
    return get_crc_value(s, crc16)


# CRC16/XMODEM
def crc16_xmodem(s):
    crc16 = mkCrcFun(0x11021, rev=False, initCrc=0x0000, xorOut=0x0000)
    return get_crc_value(s, crc16)


# common func
def get_crc_value(s, crc16):
    data = s.replace(' ', '')
    crc_out = hex(crc16(unhexlify(data))).upper()
    str_list = list(crc_out)
    if len(str_list) == 5:
        str_list.insert(2, '0')  # 位数不足补0
    crc_data = ''.join(str_list[2:])
    # return crc_data[:2] + ' ' + crc_data[2:]
    return crc_data[:2] + crc_data[2:]


def bytesToHexString(data):
    temp = []
    for i in data:
        temp.append('0x%02X' % i)
    return temp


"""
    DES-ECB 加密
    :param s: 原始字符串,密钥
    :return: 加密后字符串,16进制
    """


def des_encrypt(s, key):
    secret_key = key
    iv = secret_key
    k = des(secret_key, pyDes.ECB, IV=iv, padmode=pyDes.PAD_PKCS5)
    en = k.encrypt(s)
    return binascii.b2a_hex(en)


"""
    DES-ECB 解密
    :param s: 原始字符串,密钥
    :return: 解密后字符串,16进制
    """


def des_decrypt(s, key):
    secret_key = key
    iv = secret_key
    k = des(secret_key, pyDes.ECB, IV=iv, padmode=pyDes.PAD_PKCS5)
    en = k.decrypt(s)
    return binascii.b2a_hex(en)


if __name__ == '__main__':
    key = '1111111111111111'
    input_data = '0101e1618051991f4520329c8dec711dd986f7ebf5dcdf7aeec6'
    print("输入报文:", input_data)
    fix_mingwen = input_data[:4]
    print("输入数据的明文部分是", fix_mingwen)
    input_data_miwen = input_data[4:]
    print("输入数据的密文部分是:", input_data_miwen)
    data_body = repr(des_decrypt(bytes.fromhex(input_data_miwen), bytes.fromhex(key)))[2:-1]
    print("解密后的明文:", data_body)

    # 计算此刻的时间戳
    timestamp = hex(int(time())).strip("0x")
    print("此时的时间戳:", timestamp)

    # 计算明文
    data_body = repr(data_body)[1:29] + timestamp
    #crc16 计算有多种模式,这里用crc16_ccitt_false
    crc16_result = crc16_ccitt_false(data_body)
    data_body = data_body + crc16_result
    print("更新的时间戳的明文:", data_body)

    data_body_secrect = des_encrypt(bytes.fromhex(data_body), bytes.fromhex(key))
    data_body_secrect = repr(data_body_secrect)[2:-1]
    print("加密后的密文: ", data_body_secrect)
    data_body_secrect_all = fix_mingwen + data_body_secrect
    print("输出加密后的完整报文:", data_body_secrect_all)

    data_body_length = len(data_body_secrect_all) // 2
    dataList = []
    for i in range(0, data_body_length):
        dataList.append(data_body_secrect_all[2 * i] + data_body_secrect_all[2 * i + 1])  # 每个字节由相邻两个16机制字符组成
    data_body_kongge = " ".join(dataList)
    print("含有空格的报文表示:", data_body_kongge)

Resultados de la autoprueba:

输入报文: 0101e1618051991f4520329c8dec711dd986f7ebf5dcdf7aeec6
输入数据的明文部分是 0101
输入数据的密文部分是: e1618051991f4520329c8dec711dd986f7ebf5dcdf7aeec6
解密后的明文: 7072656668313233343536373839644335d2ff0b
此时的时间戳: 64433e0f
更新的时间戳的明文: 707265666831323334353637383964433e0f3921
加密后的密文:  e1618051991f4520329c8dec711dd986d35c06166403b220
输出加密后的完整报文: 0101e1618051991f4520329c8dec711dd986d35c06166403b220
含有空格的报文表示: 01 01 e1 61 80 51 99 1f 45 20 32 9c 8d ec 71 1d d9 86 d3 5c 06 16 64 03 b2 20

Process finished with exit code 0

4. Finalmente

        DES no se considera un algoritmo criptográfico seguro porque la clave es demasiado corta. Generalmente se recomienda actualizar al algoritmo 3DES.

Supongo que te gusta

Origin blog.csdn.net/qq_33163046/article/details/130300157
Recomendado
Clasificación