Recently github started requiring 2FA for Rust accounts. I already moved my main Rust repository to gitlab. However I still have lot small Rust repositories in github I am lazy to move too. I do not have US mobile phone, so I am looking for TOTP on Linux. Since, I do mostly Rust development, I would prefer the TOTP was Rust app too. If you know and use such, then let me know. If there is no Rust TOTP then anything CLI mode running on Linux can be helpful too.
Suggested Rust-Based TOTP Tools (CLI/Linux):
-
rathole (Rust, but primarily a tunnel tool)
-
oath-toolkit (Not Rust, but lightweight CLI for TOTP)
-
gauth (Go-based, simple CLI)
For pure Rust options, you might need to check crates like oath or totp-rs, though standalone CLI apps are rare.
Have you tried the this crate, it's a CLI written in Rust: crates.io: Rust Package Registry
I didn’t, but it looks worthy, since has only few dependencies that easy to avoid.
Maybe writting it manually is a choice.
$ cat 2fa/src/main.rs
#![feature(decl_macro)]
pub struct Secret{
val: &'static str,
algo: totp_rs::Algorithm,
digits:i32,
skew:u8,
period: u64
}
impl Secret {
pub const fn new(val:&'static str) -> Self {
Self{
val,
algo: totp_rs::Algorithm::SHA1,
digits:6,
skew:1,
period:30,
}
}
pub const fn set_algorithm(mut self, algo:totp_rs::Algorithm) -> Self {
self.algo = algo; self
}
pub const fn set_digits(mut self, digits:i32) -> Self {
self.digits = digits; self
}
pub const fn set_skew(mut self, skew:u8) -> Self {
self.skew = skew; self
}
pub const fn set_period(mut self, period:u64) -> Self {
self.period = period; self
}
pub fn secret(&self) -> Vec<u8> {
totp_rs::Secret::Encoded(self.val.to_string()).to_bytes().unwrap()
}
}
const GIT_SECRET: Secret = Secret::new("");
const USTC_CAS_SECRET: Secret = Secret::new("");
const USTC_MAIL_SECRET: Secret = Secret::new("");
const FIREFOX_SECRET: Secret = Secret::new("");
const FEISHU_SECRET: Secret = Secret::new("");
macro token($($secret:tt)*) {
use totp_rs::{Algorithm, TOTP};
$(
let totp = TOTP::new_unchecked(
Algorithm::SHA1,
$secret.digits as usize,
$secret.skew,
$secret.period,
$secret.secret()
);
let token = totp.generate_current().unwrap();
println!("totp for {} is {}",stringify!($secret), token);
)*
}
fn main() {
token! {GIT_SECRET USTC_CAS_SECRET USTC_MAIL_SECRET FIREFOX_SECRET FEISHU_SECRET}
}
The code is not conplex.
And if you worried about security, you could copy all the dependencies into your crate and check them.
The only crate you need is totp_rs. It should be fine.
I asked my AI friend what TOTP was because I had no idea. It told me and showed it diagrammatically and algorithmically.
Then I asked it to find any Rust implementations.
It just went ahead and wrote one for me!
Is it secure. I have no idea yet, but likely as secure as anything I would create to use it in.
What I did was setting up a passkey for Github on Bitwarden/1Password as that counts as 2FA.
Actually github management is concerning about security. As for me, it’s last thing I considered toward using github. I do not believe that any sane parson will consider worthy to hack my account.
Regarding dependencies
serde = { version = "1.0", features = ["derive"], optional = true }
sha2 = "0.10"
sha1 = "0.10"
hmac = "0.12"
base32 = "0.5"
urlencoding = { version = "2.1", optional = true}
url = { version = "2.4", optional = true }
constant_time_eq = "0.3"
rand = { version = "0.9", features = ["thread_rng"], optional = true, default-features = false }
zeroize = { version = "1.6", features = ["alloc", "derive"], optional = true }
qrcodegen-image = { version = "1.4", features = ["base64"], optional = true }
The list is quite big, and it it’s only first cut, because they dependent on some others increasing the list in several times.
It’s a good idea and I tried it too. The AI offered code looks decent, only hmac dependency needs to be reduced in the size. I will do it in a spare time.
I use currently a password manager I wrote in the previous century. I use to it and unlikely I will migrate.
Currently I started using totp-cli, it works great, although written in Go. You understand that using Go for Rust fan is an auto-da-fé. It has also a serious security flaw. My machine, where I setup it has no SSH server, so I was prepared physically access the machine when I need a token. But, to my surprise, I can use the app through a web terminal. I can’t only see its password request, but I know when the app requests a password and simply type it. Everything works after.
Maybe someone will be interested. The code given me by AI is generally working. However it requires security crates. I checked the crates and was amazed how good Artem wrote their code. He is genius in my opinion. However, good things are bad for me, so I decided to write the crates myself. Since JavaScript is my favorite language, I found JS implementation of hmac and converted to Rust. At the end, I wrapped my app copied Efertone’s app functionality in a web interface:
My code is also 805864 bytes, comparing to Efertone’s 4915384 bytes. Certainly Rust beats Go!
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
