use clap::{Parser, ArgGroup}; use chrono::{Utc, Duration}; use smcrypto::sm2; use std::fs; use rand::thread_rng; use rand::distributions::Alphanumeric; use rand::Rng; use base64; use regitry_code::{generate_code,decode_code, read_key_file};
#[derive(Parser)]
#[clap(name = "encrypt-utils-rust")]
#[clap(version = "1.0")]
#[clap(about = "A command line tool for SM2 encryption and decryption")]
struct Cli {
#[clap(long)]
generate_keypair: bool,
#[clap(long, value_name = "FILE")]
public_key: Option<String>,
#[clap(long, value_name = "FILE")]
private_key: Option<String>,
#[clap(long, value_name = "STRING")]
encrypt_str: Option<String>,
#[clap(long, value_name = "HEX")]
decrypt_hex: Option<String>,
#[clap(long, value_names = &["EMAIL"])]
register_code: Option<String>,
#[clap(long, value_parser = clap::value_parser!(i64))]
days: Option<i64>,
#[clap(long, value_name = "CODE")]
decode_code: Option<String>,
}
fn main() {
let cli = Cli::parse();
if cli.generate_keypair {
let (sk, pk) = sm2::gen_keypair();
fs::write("private.key", hex::encode(sk.into_bytes())).expect("Writing private key failed");
fs::write("public.key", hex::encode(pk.into_bytes())).expect("Writing public key failed");
println!("Generated key pair");
}
if let Some(email) = cli.register_code.clone() { if let Some(public_key) = cli.public_key.clone() {
if let Some(days) = cli.days {
let pk_value = read_key_file(public_key);
let code = generate_code(&email, days, &pk_value); println!("Register code: {}", code);
}
}
}
if let Some(public_key) = cli.public_key {
if let Some(encrypt_str) = cli.encrypt_str {
let pk_value = read_key_file(public_key);
let enc_ctx = sm2::Encrypt::new(&pk_value);
let enc = enc_ctx.encrypt(encrypt_str.as_bytes());
println!("Encrypted (hex): {}", hex::encode(enc));
}
}
if let Some(code) = cli.decode_code.clone() { if let Some(private_key) = cli.private_key.clone() {
let sk_value = read_key_file(private_key);
let (email, expire_time) = decode_code(&code, &sk_value); println!("Email: {}", email);
println!("Expire time: {}", expire_time);
}
}
if let Some(private_key) = cli.private_key {
if let Some(decrypt_hex) = cli.decrypt_hex {
let sk_value = read_key_file(private_key);
let dec_ctx = sm2::Decrypt::new(&sk_value);
let enc_bytes = hex::decode(decrypt_hex).expect("Decoding encrypted data failed");
let dec = dec_ctx.decrypt(&enc_bytes);
println!("Decrypted: {}", String::from_utf8(dec).expect("Invalid UTF-8"));
}
}
}