密码保护嵌入式固件下载
Password protecting embedded firmware download
我需要防止我们产品的用户下载与他们试图下载到的硬件版本不兼容的固件。我将描述目前存在的内容以及我正在寻找的内容。
我们有一个字母数字硬件部件号和修订存储在EEPROM,只有工厂可编程。当客户试图下载固件文件时,他必须输入与固件发布一起分发的密码。现有固件需要能够使用此密码来验证新固件是否与当前硬件版本兼容。请记住,多个硬件版本可能与单个发布版本的固件兼容。
是否存在某种形式的公钥加密,可用于验证在固件构建过程中生成的密钥的多个硬件修订号?硬件修订号将充当私钥,而客户为解锁下载机制输入的密码将充当公钥。
嵌入式固件是用C语言编写的,如果加密算法是相同的,那就太好了。只要它有一个可以从C函数调用的接口,它就可以是c++。
有几个硬件版本,但我们现在可以忽略它们的存在。假设一个全新的产品即将发布,它包含了这个功能,所以它将是版本0。
密码将不经过任何修改从客户端计算机传输到嵌入式硬件。因此,解密和密码匹配需要在嵌入式固件中进行,然后将成功/失败报告给客户端。这样做的原因是,它可能并不总是被用来下载固件的笔记本电脑。它更可能是一个手持下载工具,因此执行定制软件的选项有限。
忘记密码。
要做到这一点,最简单的方法是在固件文件中包含一个已知位置的兼容硬件id列表。这可以存储为长度前缀数组。当一个新的固件被加载到设备中时,设备在列表中查找它自己的硬件ID,如果不存在则拒绝该固件。这样的系统健壮,易于理解,易于调试。如果考虑到空间问题,则可以将列表存储为bitset,每个硬件版本分配一个位。
如果您希望防止主动篡改,您可以进一步签名整个固件文件,包括兼容硬件id列表,使用普通的公钥签名算法,如DSA或RSA。
所以我们假设这是一个新的设计:
我不知道你想要/需要多少安全性,你的设备有多大的处理能力……
我会让固件包由两部分组成-一个头和"真实的东西"。两者都应该以不同的方式加密,然后独立地加在一起签名(这是公钥加密部分)。
-
先检查外部签名
-
然后检查报头签名(必须根据报头,报头长度加上密码计算)
-
报头使用您分发的密码进行加密,并包含兼容硬件版本的哈希列表(这些哈希是从硬件版本+密码中计算出来的)。设备解密报头,相应地从EEPROM散列自己的修订(再次修订+密码),并尝试在列表中找到匹配。
-
用列表的哈希值检查"真实事物"的签名(根据加密内容加长度加密码加列表哈希值计算)
-
如果签名有效,则继续解密"真实的东西"(密钥将是密码+列表的哈希值)
对于签名部分,您创建一个证书,用您的根证书签名该证书…衍生的证书将嵌入到设备中……因此,您使用该证书的私钥创建签名,并使用公钥在设备中检查它们。
以上并非100%安全,但提供了以下几个方面:
- 对包的篡改总是可以检测到的(只要你没有丢失你的私钥)
- 它将无法安装在任何不兼容的硬件版本
- 找出方案不允许在不兼容的硬件版本上安装(除非您的客户以某种方式修改了您的硬件)
如果这是两次计算等等,你总是可以简化方案…至少我会保留外部签名和密码…
编辑-经过讨论(见注释):
我建议创建"密码"的基本算法由两部分组成——散列算法和加密算法:
-
散列算法
相应的固件应该被散列("好的"算法是SHA-512, SHA-384, SHA-256, MD5 -"非常弱"的算法是CRC32) 加密算法
密码将使用非对称算法(如RSA, EC等)或对称算法("强"的是AES, blowfish等-"弱"的是例如DES -"非常弱"的是例如XOR)加密
方案包括以下步骤:
-
使用上述任意散列算法对固件进行散列
-
建立一个由部件号/版本号+固件哈希值组成的字符串
-
使用上述任何加密算法加密字符串(非对称意味着您使用私钥,对称意味着您使用相同的密钥进行加密/解密)
设备需要包含一个密钥(如果使用非对称加密,则为公钥,如果使用对称加密,则为密钥)和部件号/修订号。
根据密码检查固件意味着解密密码,对固件进行哈希,并比较部件号/版本号和固件哈希…
安全方面与处理需求:
- 非对称加密意味着处理大数字(1024位或更大)
如果设备无法处理,您可能应该采取对称加密。 - 对称加密意味着如果你的客户从你的硬件中读出密钥,他将能够自己创建"有效密码",而在不对称的情况下,这将是不可能的
- 你可以只坚持哈希(哈希固件加上部件编号/版本号),并提供结果作为密码,但这让你向客户开放,让他们找出使用的算法,然后他们可以创建自己的"有效密码"
- http://www.cryptosys.net/
- http://www.openssl.org/
- http://www.cryptopp.com/
- http://en.wikipedia.org/wiki/Public-key_cryptography
- http://en.wikipedia.org/wiki/Symmetric-key_algorithm
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 为什么make_tie不是一件事
- 下载URL中的所有文件
- 写入文件会产生一个空文件或根本没有文件
- 多态杆件变量 - 类设计
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- VisualStudio:使用 Suse Enterprise Server 12 SP5 时,不会下载远程库标头
- 从 C++ 上的网址下载文件
- 在编译时,C++项目抛出错误 C2228,这是预期的,因为控件在运行时未达到该点
- 如何更改窗体上所有控件的标题?[C++生成器]
- 双击更改 mfc 中列表控件中的行的颜色
- 为大型项目编写固件时应注意的注意事项
- 从C编译器更改为C++编译器会导致MSP430固件的编译器错误
- PX4/固件出错
- 带中断的互斥安全(嵌入式固件)
- C++命名空间固件 ;矩阵乘法
- 固件文件的容器:二进制数据部分的集合
- 密码保护嵌入式固件下载
- 更新固件SDK后,PTGRey相机(Dragonfly express)无法开始捕获
- 下载并实例化COM控件