前言

最近有在WSL开发的需求,不过发现在WSL里使用Canokey智能卡签名Git Commit有些问题,因此出这一篇教程

正文

确认WSL版本

下面的步骤都需要时WSL2才能进行

1
wsl -l -v

应该类似为:

1
2
  NAME      STATE           VERSION
* Ubuntu Running 2

如果是WSL1则需要切换到WSL2

1
wsl --set-version Ubuntu 2

安装usbipd-win

1
winget install --interactive --exact dorssel.usbipd-win

插入Canokey后

1
usbipd list

应该会看到类似输出:

1
2
BUSID  VID:PID    DEVICE                                STATE
2-4 20a0:42d4 USB 输入设备, WebUSB, Microsoft Usbccid Smartcard Reader ... Not shared

这里需要记住BUSID

启动管理员命令提示符

1
usbipd bind --busid 2-4

然后输入

1
usbipd list

这时设备应该从Not shared转变为Shared

附加设备

将设备附加到WSL

1
usbipd attach --wsl --busid 2-4

此时再执行usbipd list,应该会看到Shared转变为了Attached,并且会有Windows提示音

然后进入WSL检查设备情况:

1
lsusb

应该会出现下面类似输出

1
Bus 001 Device 003: ID 20a0:42d4 Clay Logic CanoKey Canary

安装PC/SC组件

1
sudo apt install pcscd pcsc-tools libccid

启动组件

1
2
sudo systemctl enable --now pcscd.socket
sudo systemctl restart pcscd

然后检查card情况

1
pcsc_scan

如果出现智能卡信息则代表成功

如果出现Access denied,但是sudo pcsc_scan可以看到智能卡信息,则还需要一些配置:

1
sudo nano /etc/polkit-1/rules.d/49-pcscd.rules

写入(注意改用户名):

1
2
3
4
5
6
7
polkit.addRule(function(action, subject) {
if ((action.id == "org.debian.pcsc-lite.access_pcsc" ||
action.id == "org.debian.pcsc-lite.access_card") &&
subject.user == "goodboyboy") {
return polkit.Result.YES;
}
});

继续重启:

1
2
3
sudo systemctl restart polkit
sudo systemctl restart pcscd.socket
sudo systemctl restart pcscd

然后pcsc_scan应该能够正常输出智能卡信息

调整gpg配置

1
cat ~/.gnupg/scdaemon.conf

查看是否有disable-ccid字样

如果没有这个文件的话:

1
2
3
4
5
mkdir -p ~/.gnupg
chmod 700 ~/.gnupg

echo 'disable-ccid' > ~/.gnupg/scdaemon.conf
chmod 600 ~/.gnupg/scdaemon.conf

最后:

1
gpgconf --kill all

测试:

1
gpg --card-status

此时应该就能正常输出智能卡信息了

导入公钥

这个没什么好说的

1
gpg --import <公钥文件路径>

配置GPG TTY

有大概率GPG会找不到TTY,导致pinentry出现问题

可以先测试

1
2
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye

然后尝试签名:

1
git commit -S -m "test signed commit"

如果能正常显示Card PIN输入界面,即配置完成

将配置持久化:

1
nano ~/.bashrc

1
2
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye >/dev/null 2>&1

放在文件末尾

1
source ~/.bashrc