4G_module/tools/scripts/PackageSign.py

100 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
# ===================================================================
#
# Copyright © 2022 China Mobile IOT. All rights reserved.
#
# Date: 2022/08/05
# Author: zhangxw
# Function: 固件签名
#
# 签名流程①提取bin文件md5码②对md5码进行RSA签名pkcs1_15填充③将签名结果及md5码放置于bin文件开头增加固定长度256RSA + 16(MD5)
# 秘钥存储:公钥存储在模组中,私钥存储在编译环境中
#
# ===================================================================
import sys
import os.path
from Crypto.Signature import pkcs1_15
from Crypto.Hash import MD5
from Crypto.PublicKey import RSA
# 功能:固件签名
# private_key_fn 私钥文件
# bin_fn 待签名文件
# sign_fn 签名后文件
def package_sign(private_key_fn, bin_fn, sign_fn):
with open(private_key_fn) as private_key_file, \
open(bin_fn, "rb") as bin_file, \
open(sign_fn, "wb") as sign_file:
private_key = RSA.import_key(private_key_file.read())
bin_data = bin_file.read()
digest = MD5.new(bin_data) # 生成16字节MD5码
print("MD5:", digest.digest())
# 使用私钥对HASH值进行签名
signature = pkcs1_15.new(private_key).sign(digest) # 私钥签名
sign_file.write(signature) # 写入256字节签名信息
sign_file.write(digest.digest()) # 写入16字节MD5信息
sign_file.write(bin_data) # 写入固件信息
return signature
# 功能:固件验签
# public_key_fn 公钥文件
# sign_fn 签名固件
def package_check(public_key_fn, sign_fn):
with open(public_key_fn) as public_key_file, \
open(sign_fn, "rb") as sign_file:
public_key = RSA.import_key(public_key_file.read())
sign_data = sign_file.read(256) # 读取签名信息
sign_file.read(16) # 读取MD5信息
bin_data = sign_file.read() # 读取固件信息
md5_data = MD5.new(bin_data)
# print(sign_data)
print("MD5:", md5_data.digest())
try:
pkcs1_15.new(public_key).verify(md5_data, sign_data)
print("签名验证成功!!!")
except:
print("签名验证失败!!!")
# 功能:生成公私秘钥对
def pem_generate(length):
key = RSA.generate(length)
private_key = key.export_key()
public_key = key.publickey().export_key()
with open("private_key.rsa", "wb") as pri_file, \
open("public_key.rsa", "wb") as pub_file:
pri_file.write(private_key)
pub_file.write(public_key)
# 传入待签名文件,在同一个文件夹下生成签名后文件
if __name__ == "__main__":
if len(sys.argv) != 3:
print("参数错误:", len(sys.argv))
sys.exit()
bin_filename = str(sys.argv[1])
private_key_filename = str(sys.argv[2])
if os.path.isfile(bin_filename) is not True: # 判断bin文件是否存在
print("bin文件不存在", bin_filename)
sys.exit()
if os.path.isfile(private_key_filename) is not True: # 判断私钥文件是否存在
print("私钥文件不存在", private_key_filename)
sys.exit()
bin_dir = os.path.dirname(os.path.realpath(bin_filename))
bin_name = os.path.basename(bin_filename)
sign_bin_file_name = bin_dir + "\sign_" + bin_name # 签名后的文件名
print("开始签名,文件名:", bin_name)
# 将会在bin文件开头增加272固定长度包括256bytes的签名信息及16bytes的md5信息
sign = package_sign(private_key_filename, bin_filename, sign_bin_file_name) # 生成签名包
# print("签名信息:", sign)
print("签名完成,文件名:", sign_bin_file_name)
# package_check("public_key.rsa", sign_bin_file_name) # 验签