生成S19(SRecord)的数据段Hash/AES/RSA
前言
随着网络安全越来越重要,车辆的控制器的代码需要更安全的防护;以下是对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 = False
sum = 0
for i in range(0,len(data)):
sum = sum + data[i]
sum = sum & 0xFF
sum = 0xFF - sum
if sum == checksum:
rst = True
return rst
# records: error data(checksum, address continous)
# rawData: raw data(download to memeory without address)
def parse_srecord(filename):
records = []
rawData = []
offset = 0
firstAddr = False
lastAddr = 0
address = 0
dataSize = 0
with 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 - 2
if record_type == 'S1':
offset = 8
address = int(line[4:offset], 16) # 16bits
elif record_type == 'S2':
offset = 10
address = int(line[4:offset], 16) # 24bits
elif record_type == 'S3':
offset = 12
address = int(line[4:offset], 16) # 32bits
for 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) / 2
data = [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 check
if firstAddr == False:
lastAddr = address
firstAddr = True
else:
if lastAddr + dataSize != address:
records.append({
'record_type': record_type,
'byte_count': byte_count,
'address': address,
'data': data,
'checksum': checksum
})
lastAddr = address
if 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())