1 unstable release
0.1.0 | Nov 16, 2024 |
---|
#258 in Authentication
117 downloads per month
92KB
2K
SLoC
otp-std
Generating and checking one-time passwords.
Installation
cargo
You can add otp-std
as a dependency with the following command:
$ cargo add otp-std
Or by directly specifying it in the configuration like so:
[dependencies]
otp-std = "0.1.0"
Alternatively, you can add it directly from the source:
[dependencies.otp-std]
git = "https://github.com/nekitdev/otp-std.git"
Examples
For demonstration purposes, all code examples are going to use the following encoded secret:
JEQDYMZAN5YGK3RAONXXK4TDMU
.
Base
use otp_std::{Base, Secret};
fn main() {
let secret = Secret::decode("JEQDYMZAN5YGK3RAONXXK4TDMU").unwrap();
let base = Base::builder().secret(secret).build();
let input = 0;
let output = base.generate(input);
assert!(base.verify(input, output));
}
HOTP
use otp_std::{Base, Hotp, Secret};
fn main() {
let secret = Secret::decode("JEQDYMZAN5YGK3RAONXXK4TDMU").unwrap();
let counter = Counter::new(0);
let base = Base::builder().secret(secret).build();
let mut hotp = Hotp::builder().base(base).counter(counter).build();
let code = hotp.generate();
hotp.increment(); // increment the counter, as the code has been used
let other = hotp.generate();
assert_ne!(code, other); // the codes have to be different because of the increment
}
TOTP
use std::{thread::sleep, time::Duration};
use otp_std::{Base, Secret, Totp};
fn main() {
let secret = Secret::decode("JEQDYMZAN5YGK3RAONXXK4TDMU").unwrap();
let base = Base::builder().secret(secret).build();
let totp = Totp::builder().base(base).build();
let duration = Duration::from_secs(totp.period.get());
let code = totp.generate();
sleep(duration);
let other = totp.generate();
assert_ne!(code, other);
}
Features
generate-secret
The generate-secret
feature enables secret generation:
use otp_std::{Length, Secret};
fn main() {
let secret = Secret::generate(Length::default());
println!("{secret}");
}
unsafe-length
By default, otp-std
does not allow secret length below 16
bytes.
Some services, however, generate secrets with length below the aforementioned limit.
To counter this, one can enable the unsafe-length
feature:
use otp_std::{Length, Secret};
fn main() {
let length = Length::new(10).unwrap();
let secret = Secret::generate(length);
println!("{secret}");
}
Note that unwrapping here is absolutely fine, as the new
function returns Result<Self, !>
(i.e. it never returns an error). Conversely, this code would panic without unsafe-length
because
10 < 16
.
auth
The auth
feature implements building and parsing OTP URLs:
use otp_std::{Auth, Base, Label, Part, Secret, Totp};
fn main() {
let secret = Secret::decode("JEQDYMZAN5YGK3RAONXXK4TDMU").unwrap();
let base = Base::builder().secret(secret).build();
let totp = Totp::builder().base(base).build();
let issuer = Part::borrowed("MelodyKit").unwrap();
let user = Part::borrowed("nekitdev").unwrap();
let label = Label::builder().issuer(issuer).user(user).build();
let auth = Auth::totp(totp, label);
let url = auth.build_url();
println!("{url}");
let parsed = Auth::parse_url(url).unwrap();
assert_eq!(auth, parsed);
}
sha2
The default algorithm used by OTP is SHA1
. In order to use SHA256
or SHA512
, one can enable
the sha2
feature:
use otp_std::{Algorithm, Base, Secret, Totp};
fn main() {
let secret = Secret::decode("JEQDYMZAN5YGK3RAONXXK4TDMU").unwrap();
let base = Base::builder()
.secret(secret)
.algorithm(Algorithm::Sha256)
.build();
let totp = Totp::builder().base(base).build();
let code = totp.generate();
println!("{code}");
}
serde
The serde
feature, when enabled, implements Serialize
and Deserialize
for types provided
by otp-std
:
use otp_std::{Base, Secret, Totp};
use serde_json::{json, to_value};
fn main() {
let string = "JEQDYMZAN5YGK3RAONXXK4TDMU";
let data = json!({
"secret": string,
// all of the following fields are optional
"algorithm": "SHA1",
"digits": 6,
"skew": 1,
"period": 30,
});
let secret = Secret::decode(string).unwrap();
let base = Base::builder().secret(secret).build();
let totp = Totp::builder().base(base).build();
let value = to_value(&totp).unwrap();
assert_eq!(value, data);
}
Documentation
You can find the documentation here.
Support
If you need support with the library, you can send an email.
Changelog
You can find the changelog here.
Security Policy
You can find the Security Policy of otp-std
here.
Contributing
If you are interested in contributing to otp-std
, make sure to take a look at the
Contributing Guide, as well as the Code of Conduct.
License
otp-std
is licensed under the MIT License terms. See License for details.
Dependencies
~2.7–4MB
~73K SLoC