如何使用Yubikey令牌在Linux上交叉编译和签名Windows EXE

发布时间:2024/3/22 19:08:30 打印 字号:

我最近获得了一个新的代码签名证书,用于对Windows版Teensy软件进行签名。由于密钥存储规则已发生变更,并且目前关于交叉编译工作流程的信息非常少,因此我决定撰写这篇文章。

cross_compile_graphic-1-1024x481.png

基本概念是,您希望在Linux机器上轻松地为Windows编译软件。Windows EXE文件需要正确签名,以便用户看到“已验证的发布者”,并Microsoft Defender SmartScreen最终会知道您的应用程序是安全的。

这些步骤是在Ubuntu 22.04上执行的。其他Linux发行版很可能也能正常工作。

购买代码签名证书

在2023年6月之前,获取代码签名证书更简单,成本也更低。您可以创建一个私钥,并使用它发送证书签名请求 (CSR)。在验证您的身份后,证书颁发机构会将证书文件发送给您。

签名Windows EXE文件需要以下两项:一个密钥和一个由Microsoft信任的证书颁发机构颁发的证书。以前,您的计算机上只有这两个文件,或者只有一个可以同时包含这两个文件的“P12”格式文件。

自2023年6月起,您的密钥必须存储在硬件令牌中和/或证书颁发机构的云服务中。据说这样更安全。

而且价格也贵得多!买任何东西都要货比三家。价格各不相同,而且会变化。截至2024 年3月,我在Gworg上找到了最优惠的价格。本文与Gworg没有任何赞助或关联。他们只是在2024年3月提供了最优惠(最不差)的价格。“OV”的价格为每年2524元,为期3 年,硬件密钥为5340美元。Yubico的空白硬件零售价为500元。

如果您选择其他证书颁发机构,您可以联系他们确认硬件密钥是否为Yubikey FIPS。理论上,其他硬件密钥可能存在,即使现在没有,也有可能在未来某个时候出现,您需要确认他们发送的硬件是否兼容Linux 和libengine-pkcs11-openssl。

Gworg也提供云服务,无需硬件密钥,但其最低价位每年900元。这几乎和Yubikey FIPS 硬件一样贵,而且每年都一样!更糟糕的是,最低价位每年只提供5000次签名平均每个月500次都不到。Teensy的软件有几个签名的EXE文件。仅仅构建几个Beta测试版就可能意味着需要更高价位。

付款后,证书颁发机构会验证您的身份。对于“OV”级别,验证过程非常简单,以至于需要硬件令牌的成本和复杂性显得有些浪费。不过,要获得 Windows“已验证发布者”,流程就是这样的。

然后您所能做的就是等待您的Yubikey令牌到达。

收集至关重要的数据

您的Yubikey FIPS令牌将初始化为两个密码,分别为PIN码和PUK码。您的第一步是获取这两个密码。

我的Yubikey是从Gworg购买的,附带一个8位序列号,印在标签上,也印在密钥上。在 Gworg网站的订单摘要中,在“证书详情”->“物理令牌”下有一个“激活”链接。点击该链接会弹出一个对话框,要求输入8位序列号。输入序列号后,PIN码和PUK码就出现了。

其他证书颁发机构的工作方式可能有所不同,但所有Yubikey FIPS都使用这些PIN码和 PUK码来访问密钥。您必须获取证书颁发机构使用的PIN码和PUK码。如果PIN码输错3 次,密钥将被锁定。PUK 码允许您设置新的PIN码。如果PUK码输错3次,硬件将无法使用!使用密钥前,请确保您拥有正确的PIN码和PUK码。

您还需要证书数据。我在Gworg的订单摘要页面的“END ENTITY CERTIFICATES”下找到了它。它以“—–BEGIN CERTIFICATE—–”开头,包含几十行base64编码的数据,并以“—–END CERTIFICATE—–”结尾。请将其保存到文件中。任何名称都可以,我将其命名为“mycert.pem”。

安装软件

幸运的是,Ubuntu 22.04已将所需的所有软件以软件包形式提供。使用这些命令可以安装本文演示的所有内容。

sudo apt install yubikey-manager osslsigncode ykcs11 libengine-pkcs11-openssl
sudo apt install gcc-mingw-w64-i686
sudo apt install wine

如果您想在Linux上运行刚刚编译的EXE,那么您只需要(大型)wine包。

检查Yubikey硬件

现在你可以插入Yubikey并进行检查了。首先运行以下命令:

ykman list

你应该会看到它检测到你的Yubikey并打印基本信息。应该会出现8位序列号。

YubiKey 5 NFC FIPS (5.4.3) [OTP+FIDO+CCID] Serial: 00000000

输入此命令来检查存储的密钥:

ykman piv info

您应该会看到类似的结果,但使用的是实际序列号而不是零。

PIV version: 5.4.3
PIN tries remaining: 3/3
Management key algorithm: TDES
Management key is stored on the YubiKey, protected by PIN.
CHUID: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
CCC:   No data available.
Slot 84:
        Algorithm: ECCP384
        Subject DN: CN=SSL.com Code Signing Intermediate CA ECC R2,O=SSL Corp,L=Houston,ST=Texas,C=US
        Issuer DN: CN=SSL.com Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US
        Serial: 00000000000000000000000000000000000000
        Fingerprint: 0000000000000000000000000000000000000000000000000000000000000000
        Not before: 2019-03-07 19:35:47
        Not after: 2034-03-03 19:35:47
Slot 9a:
        Algorithm: ECCP384
        Subject DN: CN=PJRC.COM\, LLC,O=PJRC.COM\, LLC,L=Sherwood,ST=Oregon,C=US
        Issuer DN: CN=SSL.com Code Signing Intermediate CA ECC R2,O=SSL Corp,L=Houston,ST=Texas,C=US
        Serial: 00000000000000000000000000000000000000
        Fingerprint: 0000000000000000000000000000000000000000000000000000000000000000
        Not before: 2024-03-04 15:51:07
        Not after: 2027-03-04 15:51:07

“PIN 码剩余尝试次数”非常重要。如果您连续3次输入错误的PIN码,硬件就会被锁定。最好从Yubico网站下载图形界面的YubiKey Managers软件,并使用PUK码设置新的 PIN码。但是,如果PUK码输入错误3次,硬件就会完全锁定。解锁需要删除您花费2000元购买的密钥。

编译Windows EXE 程序

使用任何简单的C程序创建一个文件“hello.c”。

#include <stdio.h>
int main() {
    printf("Hello World\n");
    return 0;
}

使用这些命令来编译并运行代码。

i686-w64-mingw32-gcc -Os -s -o hello.exe hello.c
wine hello.exe

检查Yubikey PKCS11模块路径名

默认的PKCS11模块路径名是 /usr/lib/x86_64-linux-gnu/libykcs11.so

如果您在x86-64以外的硬件上运行 Linux(例如 Raspberry Pi),或者您使用其他Linux 发行版,则路径名可能会有所不同。在Ubuntu上,您可以使用dpkg查看ykcs11软件包安装的所有文件。

dpkg -L ykcs11
ls -l /usr/lib/x86_64-linux-gnu/libykcs11.so
ls -l /usr/lib/x86_64-linux-gnu/libykcs11.so.2
ls -l /usr/lib/x86_64-linux-gnu/libykcs11.so.2.2.0

签名你的hello.exe文件

要对新编译的EXE文件进行签名,请使用以下参数运行osslsigncode。如果您的PKCS11 模块路径名不同,请根据需要进行替换。

将XXXXXXXX替换为您的PIN码。请记住,您的 Yubikey在3次输入错误的PIN码后将被锁定!

rm -f hello2.exe
osslsigncode sign -h sha2 -pkcs11module /usr/lib/x86_64-linux-gnu/libykcs11.so -certs mycert.pem -key 'pkcs11:pin-value=XXXXXXXX' -ts http://ts.ssl.com -in hello.exe -out hello2.exe

如果hello2.exe已存在,osslsigncode会显得不太智能,并会显示一些令人困惑的错误。最好在运行osslsigncode之前确保已将其删除。

您的新hello2.exe文件是已签名的副本。复制到Windows计算机后,右键单击并查看“属性”。它应该有一个“数字签名”选项卡。单击“详细信息”应该会显示签名信息。

image-1.png

Microsoft Defender SmartScreen

遗憾的是,除非你购买了最昂贵的“EV”类型证书,否则使用新密钥的签名在 SmartScreen 中尚未生效。Windows用户会看到“不常下载”。

最终,随着越来越多的人下载和使用您的软件,SmartScreen 将开始信任它。