1个稳定版本
1.0.71 | 2023年3月26日 |
---|
#868 在 身份验证
33KB
231 代码行
cli_google_auth_from_exported_qr_jpg
CLI从Google身份验证器导出的QR jpg图像生成2FA OTP代码
版本:1.0.71 日期:2023-03-26 作者: bestia.dev 仓库: Github
标签:#rust #rustlang #教程
我的GitHub项目更像是教程而不是成品: bestia-dev教程.
GitHub上的生成文档: https://bestia-dev.github.io/cli_google_auth_from_exported_qr_jpg/
动机
在我朋友度假时丢失手机后,我意识到双因素认证(2FA)可能是个巨大的麻烦。我背得所有的主要密码,但这已经不够了。
大多数严肃的互联网服务今天都使用某种双因素认证(2FA)。我的2FA主要与我的手机相关联,如果我丢失它,我就完了。最初,互联网服务在登录时会给我发短信。这是一个糟糕的想法。如果我丢失手机,我可以在几个小时之内买一个新手机,但要从我的运营商那里获得相同电话号码的SIM卡可能很棘手。尤其是如果我身处地球另一端的外国国家。更不用说短信因为任何原因根本不起作用的情况了。据说骗子可以通过社会工程绕过基于短信的2FA。
后来,所有服务都开始采用OTP(一次性密码)的概念进行2FA,主要是TOTP(基于时间的一次性密码)。基于时间的一次性密码(TOTP)是一种计算机算法,它使用当前时间作为唯一性的来源来生成一次性密码(OTP)。TOTP是开放式认证倡议(OATH)的基石,被许多双因素认证(2FA)系统使用。它已被采用为互联网工程任务组(IETF)标准。
我在安卓手机上使用Google身份验证器应用生成许多互联网服务的2FA TOTP。我觉得还可以。TOTP是一个标准,所以我不期望不同应用程序之间有太大差异。但遗憾的是,Google身份验证器只在安卓上运行。如果我丢失手机,我就无法使用Windows或Linux计算机生成我的TOTP。这正是我想要的。
有很多针对Windows和Linux的TOTP程序,但我只是需要找个理由自己写一个。毕竟,我是一名编程爱好者/教师。
Google身份验证器可以将单个TOTP定义“传输”或“导出”为二维码。在Android上,我无法截图这个二维码,但可以用另一部手机的相机拍照。老式的愚蠢技巧!所以现在我有一个jpg图像,包含在另一台设备上生成TOTP所需的所有种子数据。二维码中的文本类似于
otpauth-migration://offline?data=...
我想将这个jpg保存在某个安全的地方。将数据放在二维码jpg中而不是文本格式中,是一种小小的混淆想法。安全性永远不是100%,这只是使黑客更难理解所发生的事情的一系列步骤。
在需要的情况下,我想有一个简单的单文件CLI程序来读取jpg中的QR码并生成我的OTP。终端中永远不输入任何秘密,只有jpg文件名。
由于这个项目的教程性质,当然必须用Rust编写。
短名称
这个开发项目的名称非常长且表达性强 cli_google_auth_from_exported_qr_jpg
。对于CLI,我希望有一个简短的名称,如 gajpg
。为了实现这一点,我只需更改/src/bin/
目录中的目录名称。然后我将使用如下行调用CLI
gajpg image1.jpg
测试数据
我仅在https://totp-online.tobythe.dev/上创建了一个TOTP种子以进行测试。
{
"account":"test",
"issuer":"tester",
"secret":"w5eq3367bie6ux4onpi3vh2mr3k3lgu27sn",
"period":30,
"digits":6,
"algorithm":"SHA-1"
}
然后我使用Android上的Google身份验证器创建了一个新的身份验证项。然后我“传输”或“导出”这个项,并在我的手机屏幕上获得了一个二维码。由于“安全性”,我无法截图。但可以用另一部相机拍照屏幕。
我将这个测试图像保存在这个项目中,命名为 image1.jpg
。
第一步从jpg中读取QR码
要从jpg中读取QR码,我将使用crate bardecoder
。在我编辑图像使其干净、黑白且对比度良好、大约700x700像素之后,它才解码我的QR码。这是我本来不想接受的更多手动工作,但这并非不可能,并且只做一次。
这个jpg图像中的QR文本是
otpauth-migration://offline?data=CioKFbdJDe%2FfCgnqX45r0bqfTI7VtZqa%2FBILdGVzdGVyOnRlc3QgASgBMAIQARgBIAAo0tfy2Qc%3D
第二步从迁移代码中获取秘密
在otpauth-migration
中,Google放入了账户、发行者和秘密。我需要提取这些。我尝试了一些现有的crate,但没有成功。
注意:双因素认证代码是秘密,你应该像对待秘密一样对待它们!
https://alexbakker.me/post/parsing-google-auth-export-qr-code.html
首先我们需要解码base64。这不难。但然后我们有一个全新的“protobuf”协议缓冲消息。
Protobuf
协议缓冲是Google创建的一种语言无关、平台无关的可扩展机制,用于序列化结构化数据。他们声称它具有高性能和效率,比json和xml更好。他们不是通用的编码器/解码器,而是为每个特定的proto消息准备优化代码。他们为20种语言创建了代码生成器,但没有为Rust创建。有一个名为prost
的crate,看起来它可以从.proto
定义生成Rust代码。我创建了一个名为code_generator
的子项目,用于从模式生成Rust代码。
生成的Rust代码被复制到gauth_migration_proto_mod.rs
。
第三步生成OTP
当我有了种子秘密,就很容易使用crate totp-rs
生成TOTP。
自动化助手
我使用我的crate cargo-auto
来编写自动化任务,如构建、发布、文档、测试等。所有这些都是用Rust代码完成的。很酷。从以下开始
cargo auto
然后按照详细的说明进行。然后继续使用明确的命令
cargo auto build
开源且免费如啤酒
我的开源项目免费如啤酒(MIT许可证)。
我简直热爱编程。
但是我也需要喝酒。如果你觉得我的项目和教程有用,请通过我的 paypal 赠送我一杯啤酒。
你知道你当地酒吧啤酒的价格;(-)所以我可以为了你的健康喝免费啤酒:(-)
依赖关系
~17–27MB
~218K SLoC