前言
随着网络安全越来越重要,车辆的控制器的代码需要更安全的防护;以下是对S19的Hash和加密操作示例,用户可以将生成的签名或加密值生成新的S19,可实现控制器的安全启动,安全访问等相关子功能。
一、准备测试的S19文件
示例S19内容文件名:HashTestS3_oneline.s19(可以使用S-Record工具先填充地址练习):本程序仅识别S1/S2/S3有效的数据段,并校验checksum和地址的连续性。
S224FAC400780000477060E0007064C4007080E0007080C05470BFE40370A0C00070DFE40326
S604012000DA
S70501040400F1
二、python处理代码
以下为AI生成后修改成需要的代码:
# pip install rsa/'File'->'Setting'
import rsa# pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import binascii# SHA1、SHA224、SHA256、SHA384、SHA512
import hashlib# check len/addr/data
def verify_checksum(data, checksum):rst = Falsesum = 0for i in range(0,len(data)):sum = sum + data[i]sum = sum & 0xFFsum = 0xFF - sumif sum == checksum:rst = Truereturn rst# records: error data(checksum, address continous)
# rawData: raw data(download to memeory without address)
def parse_srecord(filename):records = []rawData = []offset = 0firstAddr = FalselastAddr = 0address = 0dataSize = 0with open(filename, 'r') as file:for line in file:record_type = line[0:2]if record_type == 'S1' or record_type == 'S2' or record_type == 'S3':byte_count = int(line[2:4], 16)data_end = 4 + 2 * byte_count - 2if record_type == 'S1':offset = 8address = int(line[4:offset], 16) # 16bitselif record_type == 'S2':offset = 10address = int(line[4:offset], 16) # 24bitselif record_type == 'S3':offset = 12address = int(line[4:offset], 16) # 32bitsfor i in range(offset, data_end, 2):byte_value = int(line[i:i + 2], 16)#hex_value = byte_value.to_bytes(1,byteorder='little')rawData.append(byte_value)dataSize = (data_end - offset) / 2data = [int(line[i:i + 2], 16) for i in range(2, data_end, 2)] # for checksum(check len/addr/data)checksum = int(line[data_end: data_end + 2], 16)# address continous checkif firstAddr == False:lastAddr = addressfirstAddr = Trueelse:if lastAddr + dataSize != address:records.append({'record_type': record_type,'byte_count': byte_count,'address': address,'data': data,'checksum': checksum})lastAddr = addressif verify_checksum(data, checksum) == False:records.append({'record_type': record_type,'byte_count': byte_count,'address': address,'data': data,'checksum': checksum})return [records,rawData]# sha1 output = 160(bits)
# input=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
# output=9e5175008751d08f361488c9927086b276b965fa
def calculate_sha1(data):hashObj = hashlib.sha1()hashObj.update(data)return hashObj.hexdigest()# SHA512 output = 512(bits)
# input=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
# output=5a944f3eaf5e8412fcffc48e01a313848cf95f511d0b0667332a4adc5803793a58fe6646d04fc2d9160a43c57ab68545e3298b3cb3ba2284e605edffda603287
def calculate_sha512(data):hashObj = hashlib.sha3_512()hashObj.update(data)return hashObj.hexdigest()
三、生成结果
# Process SRecord
print("-----------------Process SRecord------------------")
s19File = 'HashTestS3_oneline.s19'[srecords, srawDatas] = parse_srecord(s19File)
# check checksum and address error
if len(srecords) > 0:print("SRecord format error! ")
else:print("Process SRecord Finish OK!")# HASH demo
print("-------------------HASH demo-------------------")
sha1 = calculate_sha1(bytes(srawDatas)) # bytes(srawDatas) for convert ’int' to ‘byte'
sha512 = calculate_sha512(bytes(srawDatas))
print("[ sha1 ]: " + sha1 + " Bit len = " + str(int(len(sha1)/2*8)))
print("[sha512]: " + sha512 + " Bit len = " + str(int(len(sha512)/2*8)))# ASE demo
print("-------------------AES demo-------------------")
key = b'Sixteen byte key'
# MODE_CBC mode
cipher = AES.new(key, AES.MODE_CBC)
decryptor = AES.new(key, AES.MODE_CBC, iv=cipher.iv)
# 明文数据
message = bytes(srawDatas)
# 加密
ciphertext = cipher.encrypt(pad(message, AES.block_size))
# 解密
plaintext = unpad(decryptor.decrypt(ciphertext), AES.block_size)
print('[AES明文]: ', binascii.hexlify(message).decode())
print('[AES密文]: ', binascii.hexlify(ciphertext).decode())
print('[AES解密后的明文]: ', binascii.hexlify(plaintext).decode())# RSA demo
print("-------------------RSA demo-------------------")
(public_key, private_key) = rsa.newkeys(3072)
print('[RSA公钥]:', public_key)
print('[RSA私钥]:', private_key)message = bytes(srawDatas)
ciphertext = rsa.encrypt(message, public_key)
plaintext = rsa.decrypt(ciphertext, private_key)
print('[RSA明文]: ', binascii.hexlify(message).decode())
print('[RSA密文]: ', binascii.hexlify(ciphertext).decode())
print('[RSA解密后的明文]: ', binascii.hexlify(plaintext).decode())