Scanning QR codes to import keys

一篇笔记,记录一下实现App里扫码导入PGP Keys和SSH Keys的过程中遇到的问题。

首先遇到的问题是private keys可能很长,装不进一个QR code里,只能拆成多张QR codes。想到的解决方案有两种。

  • 用户端着手机手动一张一张地扫QR code,最后扫码的结果拼起来是一个完整的Key。
  • 支持扫多张QR codes串起来按顺序循环播放的gif,好处是扫起来比较顺手,只要端着手机对着gif等着自动一张一张扫完(滴滴滴滴滴滴-done)。

最后决定选择第二种方法,因为扫起来比较爽。而且假设可以自动识别第一张和最后一张QR Code,实现第二种方案的同时也算是默默地支持了第一种方案,毕竟手动点“下一张”来换QR Code的效果等价于播放了一个不循环的gif。趁此机会也学习一下PGP和SSH key的格式(有趣而无用的知识?)。

PGP Keys

这里只考虑扫ASCII-armored Keys转成的QR codes。根据OpenPGP Message Format (RFC 4880)的Forming ASCII Armor,OpenPGP实现的key应该都长这样。 Public keys:

-----BEGIN PGP PUBLIC KEY BLOCK-----
xxxxx
-----END PGP PUBLIC KEY END-----

Private keys:

-----BEGIN PGP PRIVATE KEY BLOCK-----
xxxxx
-----END PGP PRIVATE KEY END-----

所以找到第一张gif和最后一张gif都很容易,只要找找-----BEGIN-----END就行了。

SSH Keys

想写导入SSH Keys的时候有点儿懵,因为发现自己的public key的长相是ssh-rsa xxxxxx== [email protected],而private key又像PGP keys一样有-----BEGIN-----END

Private Key

首先先研究一下private key。看了下面这三个链接,感觉”—–BEGIN”和”—–END”是靠谱的begin/end marker,所以找到第一张gif和最后一张gif都很容易。

Public Key

The Secure Shell (SSH) Public Key File Format (RFC 4716) 这里头写着SSH2的public key是由BEGIN开头END结尾的。所以,SSH2格式的public key可以轻松确定哪一张QR code是第一张或者最后一张。

ArchLinux Wiki里的SSH_Keys总结了一下OpenSSH支持的key type,好多啊。照着翻了翻Spec。

现在问题来了,上面几种OpenSSH的public key没有end marker:如果这个gif不巧又只有一个QR code,无法判断这个唯一的gif到底还有没有“下一页”;如果就算key被分成了多页gif code,得扫描完最后一张又重新扫描一次第一张,才知道上一张已经是最后一张。

最后的结论是,public key其实可以由private key reconstruct出来,就不导入了……