Bootstrap

对称算法(symmetric_alg.py),bytes操作,包含如3des,aes等

"""
symmetric_alg.py 对bytes的操作
Author: tanglei
DateTime:2024-11-18 完成
微信:ciss_cedar
欢迎一起学习
需要IV的加密模式:CBC、OFB、CFB、CFB8
加密算法:["AES","Camellia","TripleDES","Blowfish","CAST5","ARC4","IDEA","SEED","ChaCha20","SM4"]
#ChaCha20 需要nonce ARC4 有漏洞。
"""
import os
from enum import Enum

from Cryptodome.Util.Padding import pad, unpad
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes


class CipherMode(Enum):
    ECB,CBC,CFB,OFB,CTR='ECB', 'CBC', 'CFB', 'OFB', 'CTR'

class AlgName(Enum):
    AES ,Camellia,TripleDES,Blowfish,CAST5, IDEA, SEED, SM4=\
        ('AES', 'Camellia', 'TripleDES', 'Blowfish', 'CAST5', 'IDEA',
         'SEED', 'SM4')


class MySymCipher:
    block_size = 16
    style = 'pkcs7'
    MODE_NAME = ['ECB', 'CBC', 'CFB', 'OFB', 'CTR']
    ALG_NAME = ['AES', 'Camellia', 'TripleDES', 'Blowfish', 'CAST5', 'IDEA', 'SEED', 'SM4']
    key_sizes = frozenset([128, 192, 256])


    def __init__(self,key,iv,mode,alg_name):
           self.key=key
           self.iv=iv  #认为 nonce
           self.mode=self.get_model(mode,iv)
           self.alg_name=self.valid_alg_name(alg_name)
        #algorithm=getattr(hashes, self.hash_name)
    @staticmethod
    def get_model(mode, iv):
        if mode not in MySymCipher.MODE_NAME:
            raise "unsupported modes, confirm the input Mode name"
        modes_dict = {
            'ECB': modes.ECB(),
            'CBC': modes.CBC(iv),
            'CFB': modes.CFB(iv),
            'OFB': modes.OFB(iv),
            'CTR': modes.CTR(iv),# 认为iv 是nonce
        }
        return modes_dict.get(mode.upper())

    @staticmethod
    def valid_alg_name(alg_name):
        if alg_name not in MySymCipher.ALG_NAME:
            raise "unsupported alg, confirm the input ALG_NAME name"
        return alg_name

    def encrypt_bytes(self, plain_bytes):
        """
        输入字符串,完成加密操作
        :param plaintext 明文字符串 bytes
        :return: 16进制密文字符串
        """
        # bytes后的填充数据
        data_padding = pad(plain_bytes, self.block_size, self.style)
        # 加密对象AES,SM4

        algorithm = getattr(algorithms, self.alg_name)

        my_alg = Cipher(algorithm(self.key), self.mode)
        encryptor = my_alg.encryptor()
        # 加密操作完成
        encrypt_bytes = encryptor.update(data_padding) + encryptor.finalize()
        return encrypt_bytes

    def decrypt_bytes(self, cipher_bytes):
        """
        输入16进制密文数据,返回原文
        :param ciphertext: 16进制密文数据字符串
        :return:
        """
        algorithm = getattr(algorithms, self.alg_name)
        my_alg = Cipher(algorithm(self.key), self.mode)
        decrypt = my_alg.decryptor()
        # 解密操作完成
        pad_decrypt_value = decrypt.update(cipher_bytes) + decrypt.finalize()
        decrypt_bytes = unpad(pad_decrypt_value, self.block_size, self.style)
        # 转为大写的16进制字符串输出
        return decrypt_bytes

    @staticmethod
    def gen_random_bytes(length=16):
        # 使用软件算法,可以调用系统函数或者使用secrets生成随机数再进行派生
        # 当前使用32字符,16字节的随机数也是可以的。
        random_bytes= os.urandom(length)
        return random_bytes
def main():
    key128 = '2934412A66B7A186DC35DC40E926F9EE'
    key192 = '2934412A66B7A186DC35DC40E926F9EE2934412A66B7A186'
    key256 = '2934412A66B7A186DC35DC40E926F9EE2934412A66B7A186DC35DC40E926F9EE'
    iv = '86CD720D75F4622DBE96078A3CD1076E'
    key = bytes.fromhex(key128)
    alg_name = AlgName.AES.value
    mode = CipherMode.ECB.value
    iv = bytes.fromhex(iv)
    my_alg = MySymCipher(key, iv, mode, alg_name)
    source = b'1'

    cipher = my_alg.encrypt_bytes(source)
    plain = my_alg.decrypt_bytes(cipher)
    print(f'alg_name={alg_name},mode={mode}')
    print(f'key={key},iv={iv}')
    print(f'source=', source)

    print(f'cipher={cipher}')
    print(f'cipher.Hex: {cipher.hex().upper()}')
    print(f'plain={plain}')
    print(f'plain.decode= {plain.decode()}')
    # AES_ECB:7F0AFB6D64764FAF13D73EDBA225F142
    # AES_CBC:3C6A796A00C52E41B1FDECF4206DDA1C
    # AES_CTR:5F30BCC30D7634F2C1D6411B674BC569
    # SM4_ECB:4B622D9C120C4FE245567C496684E2F0
    # SM4_CBC:42A3696426D3F0DCBDD7A58E17352BA3
    # SM4_CTR:7489C0A4178D449B912D2F78AF2F22A2


if __name__ == '__main__':
    main()

;