UEFI开发学习27 – Secure Boot Key 的生成及签名

前面两篇写了secure boot的一些理论知识,内容比较枯燥,这一篇文章将结合QEMU做一个实验,来进一步加深对安全启动的理解。这个实验主要涉及几个方面:比如如何让QEMU支持secure boot、如何生成secure boot key、以及如何给efi文件签名。

一、编译支持安全启动的QEMU固件

用常规的方式编译OvmfPkg是不支持安全启动的,如果要添加该功能支持,编译的时候需要加入一个参数:

-D SECURE_BOOT_ENABLE

完整命令为:

    build -p OvmfPkg/OvmfPkgX64.dsc -t VS2015x86 -a X64 -b RELEASE -D SECURE_BOOT_ENABLE

    编译完后使用下面命令启动QEMU:

    qemu-system-x86_64.exe -pflash EDK2代码路径BuildOvmfX64release_VS2015x86FVOVMF.fd -net none

    在 QEMU 启动界面按 F2 或在 shell 输入 exit 可进入setup界面,打开Device Manager可看到Secure Boot Configuration选项,这样便可以支持安全启动了,如下图:

    二、生成安全启动证书

    前文中成功启用了安全启动支持,但默认是没有加入相关证书的,所以安全启动并没有生效。

    要打开安全启动,需要我们导入证书链:PK证书、KEK证书以及DB证书。当前我们并没有这些证书,为了满足测试需要,下面就来手动生成。

    证书的生成需要用到openssl,可自行在网上下载或用everything在本地搜索一下,很多工具、代码都会内置openssl,搜到的话直接拿来用即可。

    回忆一下之前的内容,Secure Boot Key 之间是要建立信任链的,也就是DB证书由KEK签名,KEK证书由PK签名,PK则是自签名证书。知道了这层关系,下面来逐个生成。

    2.1 生成PK证书

    首先生成一个Private Key,即私钥:

    openssl genrsa -out "keysPK.key" 2048

    设置openssl.cnf的路径:

    SET OPENSSL_CONF=.openssl.cnf

    生成PK自签名证书(自签名证书无需生成证书请求文件)

    openssl req -new -x509 -key "keysPK.key" -out "keysPK.crt" -days 3650 -subj "/CN=AY123 PK/OU=AY123.NET"

    这样便在keys目录下生成一个自签名的PK证书,双击crt文件,可以看到颁发者和颁发对象,有效期10年,如下图:

    2.2 生成KEK证书

    生成KEK私钥

    openssl genrsa -out "keysKEK.key" 2048

    KEK证书要被PK签名,需要先生成证书请求文件

    openssl req -new -key "keysKEK.key" -out "keysKEK.csr" -subj "/CN=AY123 KEK/OU=AY123.NET"

    使用PK私钥签名KEK

    openssl x509 -req -in "keysKEK.csr" -CA "keysPK.crt" -CAkey "keysPK.key" -CAcreateserial -out "keysKEK.crt" -days 3650

    2.3 生成DB证书

    生成DB私钥

    openssl genrsa -out "keysDB.key" 2048

    生成DB证书请求文件

    openssl req -new -key "keysDB.key" -out "keysDB.csr" -subj "/CN=AY123 DB/OU=AY123.NET"

    使用KEK私钥签名DB

    openssl x509 -req -in "keysDB.csr" -CA "keysKEK.crt" -CAkey "keysKEK.key" -CAcreateserial -out "keysDB.crt" -days 3650

    2.4 转换为DER格式证书

    UEFI 中,只能支持DER格式的证书,而前面生成的证书都是PEM格式的需要对其进行转换,命令如下:

    openssl x509 -outform der -in "keysPK.crt" -out "keysPK.cer"openssl x509 -outform der -in "keysKEK.crt" -out "keysKEK.cer"openssl x509 -outform der -in "keysDB.crt" -out "keysDB.cer"

    区分PEM格式和DER格式最好的方法是直接用记事本打开证书,如果是文本,则是PEM格式,如果打开乱码,则是DER格式。

    至此证书链生成、建立完毕!

    三、导入证书

    为了方便导入证书,可在启动QEMU的命令中加入一个本地目录作为磁盘的参数:

    -hda fat:rw:EDK2代码路径BuildAppPkgDEBUG_VS2015x86X64

    完整命令为:

    qemu-system-x86_64.exe -pflash EDK2代码路径BuildOvmfX64release_VS2015x86FVOVMF.fd -net none -hda fat:rw:EDK2代码路径BuildAppPkgDEBUG_VS2015x86X64

    将证书文件放入此目录,进入 shell 或 setup 便可访问。

    设置好参数后,启动QEMU,进入 Secure Boot Configuration 界面,将 Standard Mode 设置为 Custom Mode,接着进入 Custom Secure Boot Options。

    依次添加 DB、KEK 最后再添加 PK,每添加完一个证书点一下Commit changes and exit。

    重启进入shell,试着访问Hello.efi,提示错误,表示Secure Boot成功启用了。

    四、签名

    为了能够在 secure boot 状态下运行 EFI APP ,需要使用 DB 的私钥对 EFI 文件进行签名。签名需要用到的工具是微软的 signtool ,也能在 EWDK 中找到。使用 signtool 进行签名,需要一个 pfx 的私钥,前文生成的 private key 不是这种格式,需要对其转换:

    openssl pkcs12 -export -out "keysDB.pfx" -inkey "keysDB.key" -in "keysDB.crt" -password pass:PrivateKeyPassword
    提示:命令中 PrivateKeyPassword 表示要设置的密码

    接下来可以使用 signtool 签名了,命令如下:

    signtool sign /v /fd SHA256 /t http://timestamp.digicert.com /f keysDB.pfx /p PrivateKeyPassword Hello.efi

    由于使用timestamp验证方式,需要联网,注意网络通畅,否则签名失败。

    签名后,将文件放到 QEMU 目录,重新启动 QEMU,执行签名过的文件,可成功运行:

    五、拓展

    由于 secure boot key 是我们自己生成,secure boot 启用后,还能启动 windows 吗?将Windows的引导文件执行一下试试,发现同样报错:

    这是因为引导文件使用的是 Windows 的签名,需要加入 Windows 的 DB 证书,DB 证书只包含公钥,是公开的,可在微软网站下载。根据微软描述,以下 2 个证书必须包含在数据库中,才能允许 Windows OS 加载程序加载:

    • Windows Production PCA 2011:https://go.microsoft.com/fwlink/p/?linkid=321192
    • Windows UEFI CA 2023:https://go.microsoft.com/fwlink/?linkid=2239776

    将此两个 DB 证书加入到QEMU后,在shell可成功执行引导文件。

    除了微软的 DB 证书,还有第三方的 UEFI 证书,用于启动第三方的应用程序,如网卡的PXE驱动,有兴趣的可以去realtek网站下载一个efi试验一下,这里就不一 一写了。

    五、附件

    为了方便使用,我已经将命令整理成2个bat文件,可以一键生成证书和签名,已传至我的gitee项目:

    https://gitee.com/ay123net/uefistudy

    版权声明:
    作者:bin
    链接:https://ay123.net/mystudy/uefi/1739/
    来源:爱影博客
    文章版权归作者所有,未经允许请勿转载。

    THE END
    分享
    二维码
    海报
    UEFI开发学习27 – Secure Boot Key 的生成及签名
    前面两篇写了secure boot的一些理论知识,内容比较枯燥,这一篇文章将结合QEMU做一个实验,来进一步加深对安全启动的理解。这个实验主要涉及几个方面:……
    <<上一篇
    下一篇>>
    文章目录
    关闭
    目 录