汽车网络安全 - AES加密算法说明和实现大汇总


前言

汽车网络安全中,经常会用到很多加解密和验签算法,今天说说加密算法的原理和算法实现,可以助于理解加密算法以及加密算法编写的正确性。

一、汽车网络安全中加密算法和验签的应用场景

1.安全启动

确保启动程序的真实性,加密算法应用:汽车的启动程序(如引导加载程序 Bootloader)通常会使用加密算法进行保护。可以采用哈希算法(如 SHA - 256)对启动程序进行哈希计算,生成一个固定长度的哈希值。这个哈希值就像是启动程序的 “指纹”,只要启动程序的内容发生任何微小的变化,哈希值都会截然不同。然后,将哈希值与启动程序一起存储,并使用加密算法对哈希值进行加密,防止其被篡改。
验签应用:在车辆启动时,硬件会首先加载启动程序。在加载过程中,会对启动程序的哈希值进行解密,并重新计算启动程序的哈希值,将两者进行对比。同时,还会验证哈希值的签名,以确保哈希值的真实性和完整性。通过这种方式,可以防止攻击者替换或篡改启动程序,保证车辆从可信的启动程序开始启动

2.软件更新

加密算法应用:汽车制造商通过网络向车辆推送软件更新包,为了防止更新包在传输过程中被篡改或窃取,使用加密算法对更新包进行加密。例如,采用 SHA - 256 算法对更新包进行哈希计算,生成一个唯一的哈希值,并将其与更新包一起发送给车辆。车辆在接收更新包后,会重新计算更新包的哈希值,并与收到的哈希值进行对比,以确保更新包的完整性。
验签应用:车辆在接收软件更新时,需要验证更新包的来源是否合法。汽车制造商在发布更新包时会对其进行数字签名,车辆通过验证签名来确认更新包是否由合法的制造商发布,从而防止恶意软件伪装成更新包被安装到车辆

二、AES-CBC工作原理

1.加密过程

首先,将明文分成固定长度的块,通常 AES 中块大小为 128 位。然后,对于第一个明文块,会与一个随机生成的初始向量(Initialization Vector,IV)进行异或操作,再将结果用 AES 密钥进行加密,得到第一个密文块。后续的每个明文块在加密前,都要先与前一个密文块进行异或操作,然后再用 AES 密钥加密,以此类推。这样,每个密文块的生成不仅取决于当前的明文块和密钥,还与前面的密文块相关,形成了一种链式结构,这也是 CBC 模式名称的由来。

2.解密过程

与加密过程相反,先对密文块用 AES 密钥进行解密,然后将解密后的结果与前一个密文块(对于第一个密文块则是与初始向量 IV)进行异或操作,得到明文块。按照这个顺序依次处理每个密文块,最终还原出原始明文。

3.实现过程

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import unpad

# 生成随机的16字节密钥
key = get_random_bytes(16)
iv = b'\x00' * AES.block_size

key = "ff571fb34877bb4ee87a7233b3e5571f".encode('utf-8')
print("key:",key.hex())

# 待加密的明文
plaintext = "Hello, AES encryption!".encode('utf-8')
plaintext = get_random_bytes(16)
#print("plaintext:",plaintext.decode('utf-8'))
print("plaintext:",plaintext.hex)

# 创建AES加密器,使用CBC模式
cipher = AES.new(key, AES.MODE_CBC,iv)

cipher.iv = b'\x00' * AES.block_size
# 填充明文数据到AES块大小的倍数
padded_plaintext = pad(plaintext, AES.block_size)


# 加密数据
ciphertext = cipher.encrypt(padded_plaintext)
print("加密后的密文:", ciphertext.hex())


print("iv:",cipher.iv.hex())


#解密数据
#decipher = AES.new(key, AES.MODE_CBC, cipher.iv)
decipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_text = decipher.decrypt(ciphertext)
#unpadded_text = decrypted_text.rstrip(b'\0')
# 去除填充
unpadded_text = unpad(decrypted_text, AES.block_size)

#print("解密后的明文:", unpadded_text.decode('utf-8'))
print("解密后的明文:", unpadded_text.hex)

4.实现结果

在这里插入图片描述

三、AES-EBC工作原理

1.加密过程

将明文按照 AES 算法规定的块大小(通常为 128 位)进行分组。
对每一个明文分组,使用相同的 AES 密钥独立地进行加密操作。每个分组的加密过程完全相同,不受其他分组的影响,就像在一个密码本中查找对应的密文一样,所以称为电子密码本模式。例如,有明文数据 “ABCDEFGHIJKL”,分成 “ABCDEFGH” 和 “IJKL” 两个分组(假设块大小为 8 位),分别用 AES 密钥对这两个分组进行加密,得到两个密文分组

2.解密过程

与加密过程相反,将接收到的密文按照块大小进行分组。
然后使用相同的 AES 密钥对每个密文分组独立地进行解密操作,得到对应的明文分组。最后将所有明文分组组合起来,就还原出了原始明文

3.实现过程

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os

# 生成一个16字节(128位)的密钥,在实际应用中,密钥应该妥善保管
key = os.urandom(16)


def aes_ecb_encrypt(plaintext, key):
    """
    使用AES ECB模式对明文进行加密
    :param plaintext: 待加密的明文,类型为字符串
    :param key: 加密密钥,类型为字节串
    :return: 加密后的密文,类型为字节串
    """
    # 创建AES加密器,使用ECB模式
    cipher = AES.new(key, AES.MODE_ECB)
    # 将明文编码为字节串,并进行填充
    padded_plaintext = pad(plaintext.encode(), AES.block_size)
    # 执行加密操作
    ciphertext = cipher.encrypt(padded_plaintext)
    return ciphertext


def aes_ecb_decrypt(ciphertext, key):
    """
    使用AES ECB模式对密文进行解密
    :param ciphertext: 待解密的密文,类型为字节串
    :param key: 解密密钥,类型为字节串
    :return: 解密后的明文,类型为字符串
    """
    # 创建AES解密器,使用ECB模式
    cipher = AES.new(key, AES.MODE_ECB)
    # 执行解密操作
    decrypted_padded = cipher.decrypt(ciphertext)
    # 去除填充
    decrypted_text = unpad(decrypted_padded, AES.block_size)
    # 将解密后的字节串解码为字符串
    return decrypted_text.decode()


# 待加密的明文
plaintext = "AES ECB TEST!"
# 执行加密操作
encrypted = aes_ecb_encrypt(plaintext, key)
# 执行解密操作
decrypted = aes_ecb_decrypt(encrypted, key)

print("原始明文:", plaintext)
print("加密后的密文:", encrypted.hex())
print("解密后的明文:", decrypted)
    

4.实现结果

四、AES-CMAC说明与实现

AES - CMAC 是一种基于高级加密标准(AES)的认证加密模式,全称为 Cipher - based Message Authentication Code(基于密码的消息认证码)

1.工作原理过程

参考文档 https://blog.youkuaiyun.com/xiaohuanxiong_/article/details/139493386
在这里插入图片描述

2.实现过程

from Crypto.Cipher import AES
from Crypto.Util.strxor import strxor
from Crypto.Util.Padding import pad

def left_shift(data):
    """
    对字节数据进行左移操作
    """
    result = bytearray(len(data))
    carry = 0
    for i in reversed(range(len(data))):
        result[i] = ((data[i] << 1) & 0xff) | carry
        carry = (data[i] >> 7) & 1
    if carry:
        result[-1] ^= 0x87
    return bytes(result)

def generate_subkeys(key):
    """
    生成 AES - CMAC 的子密钥
    """
    cipher = AES.new(key, AES.MODE_ECB)
    zero_block = b'\x00' * 16
    l = cipher.encrypt(zero_block)
    k1 = left_shift(l)
    k2 = left_shift(k1)
    return k1, k2

def aes_cmac(key, message):
    """
    计算 AES - CMAC
    """
    k1, k2 = generate_subkeys(key)
    block_size = 16
    padded_message = pad(message, block_size)
    num_blocks = len(padded_message) // block_size

    if num_blocks == 0:
        padded_message = b'\x00' * block_size
        num_blocks = 1

    x = b'\x00' * block_size
    cipher = AES.new(key, AES.MODE_ECB)

    for i in range(num_blocks - 1):
        block = padded_message[i * block_size:(i + 1) * block_size]
        x = cipher.encrypt(strxor(x, block))

    last_block = padded_message[(num_blocks - 1) * block_size:]
    if len(message) % block_size == 0:
        last_block = strxor(last_block, k1)
    else:
        last_block = strxor(last_block, k2)

    cmac = cipher.encrypt(strxor(x, last_block))
    return cmac

# 示例使用
key = b'\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c'
message = b"AES-CMAC TEST!"
cmac = aes_cmac(key, message)
print("AES-CMAC:", cmac.hex())

    

3.实现结果

在这里插入图片描述

五、SHA-256原理与实现

1.SHA-256原理

SHA256 是一种密码散列函数,属于 SHA - 2(安全散列算法 2)家族中的一员,由美国国家安全局(NSA)设计,美国国家标准与技术研究院(NIST)发布。SHA256 算法基于 Merkle - Damgård 结构,通过对输入数据进行分组处理,经过一系列复杂的数学运算,包括位操作、逻辑运算和加法运算等,最终生成一个 256 位(32 字节)的哈希值。

2.实现过程

import hashlib

# 要计算哈希值的字符串
input_string = "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b"
#input_string = "1"


# 将字符串编码为字节类型
input_bytes = input_string.encode('utf-8')
# 创建SHA - 256哈希对象
hash_object = hashlib.sha256(input_bytes)
# 获取十六进制表示的哈希值
hash_hex = hash_object.hexdigest()

print("输入字符串:", input_string)
print("SHA - 256哈希值:", hash_hex)

3.实现结果

在这里插入图片描述

总结

后续添加ECDSA等更多的汽车网安相关算法说明和实现,欢迎点赞关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值