mirror of
https://github.com/kristoferssolo/cipher-workshop.git
synced 2025-12-20 11:04:38 +00:00
feat(cli): add AES to cli app
This commit is contained in:
parent
5b3ca7eacf
commit
051bba33a8
@ -107,7 +107,7 @@ fn parse_radix(s: &str, radix: u32) -> Result<u128, BlockError> {
|
||||
}
|
||||
|
||||
fn ascii_string_to_u128(s: &str) -> Result<u128, BlockError> {
|
||||
if s.len() > 8 {
|
||||
if s.len() > 16 {
|
||||
return Err(BlockError::InvalidByteStringLength(s.len()));
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{CipherAction, CipherError, CipherResult, Output};
|
||||
/// Implements the standard encrypt/decrypt interface for block ciphers.
|
||||
/// Implementers define `transform_impl` to handle the core algorithm,
|
||||
/// while `transform` provides validation and convenience wrappers.
|
||||
pub trait BlockCipher: Sized {
|
||||
pub trait BlockCipher {
|
||||
const BLOCK_SIZE: usize;
|
||||
|
||||
fn from_key(key: &[u8]) -> Self;
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use cipher_core::{BlockCipher, InputBlock};
|
||||
use des::Des;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
@ -9,16 +7,6 @@ pub enum Algorithm {
|
||||
Aes,
|
||||
}
|
||||
|
||||
impl Algorithm {
|
||||
#[must_use]
|
||||
pub fn get_cipher(&self, key: &impl InputBlock) -> impl BlockCipher {
|
||||
match self {
|
||||
Self::Des => Des::from_key(key.as_bytes()),
|
||||
Self::Aes => todo!("Must implement AES first"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Algorithm {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let s = match self {
|
||||
|
||||
@ -18,9 +18,9 @@ impl OutputFormat {
|
||||
#[must_use]
|
||||
pub fn to_string(&self, value: &Output) -> String {
|
||||
match self {
|
||||
Self::Binary => format!("{value:064b}"),
|
||||
Self::Octal => format!("{value:022o}"),
|
||||
Self::Hex => format!("{value:016X}"),
|
||||
Self::Binary => format!("{value:b}"),
|
||||
Self::Octal => format!("{value:o}"),
|
||||
Self::Hex => format!("{value:X}"),
|
||||
Self::Text => format!("{value}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
use cipher_factory::{Algorithm, OperationChoice, OutputFormat};
|
||||
use clap::Parser;
|
||||
use des::Block64;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
@ -15,12 +13,12 @@ pub struct Args {
|
||||
pub algorithm: Algorithm,
|
||||
|
||||
/// Key used for encryption/decryption. Can be a string or a path to a file
|
||||
#[arg(short, long, value_parser = Block64::from_str, required = true)]
|
||||
pub key: Block64,
|
||||
#[arg(short, long, required = true)]
|
||||
pub key: String,
|
||||
|
||||
/// The text to encrypt/decrypt. Can be a string or a path to a file
|
||||
#[arg(value_name = "TEXT", value_parser = Block64::from_str, required = true)]
|
||||
pub text: Block64,
|
||||
#[arg(value_name = "TEXT", required = true)]
|
||||
pub text: String,
|
||||
|
||||
/// Output format for decrypted data
|
||||
#[arg(short = 'f', long)]
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
mod args;
|
||||
|
||||
use crate::args::Args;
|
||||
use aes::{Aes, Block128};
|
||||
use cipher_core::BlockCipher;
|
||||
use cipher_factory::OperationChoice;
|
||||
use cipher_factory::{Algorithm, OperationChoice, OutputFormat};
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::{Ok, Result};
|
||||
use des::{Block64, Des};
|
||||
use std::str::FromStr;
|
||||
|
||||
fn main() -> color_eyre::Result<()> {
|
||||
fn main() -> Result<()> {
|
||||
color_eyre::install()?;
|
||||
let Args {
|
||||
operation,
|
||||
@ -15,18 +19,40 @@ fn main() -> color_eyre::Result<()> {
|
||||
output_format,
|
||||
} = Args::parse();
|
||||
|
||||
match operation {
|
||||
OperationChoice::Encrypt => {
|
||||
let cipher = algorithm.get_cipher(&key);
|
||||
let ciphertext = cipher.encrypt(&text.to_be_bytes())?;
|
||||
println!("{ciphertext:016X}");
|
||||
match algorithm {
|
||||
Algorithm::Des => {
|
||||
let key = Block64::from_str(&key)?;
|
||||
let text = Block64::from_str(&text)?;
|
||||
let cipher = Des::from_key(&key.to_be_bytes());
|
||||
execute_cipher(operation, &cipher, &text.to_be_bytes(), output_format)?;
|
||||
}
|
||||
OperationChoice::Decrypt => {
|
||||
let cipher = algorithm.get_cipher(&key);
|
||||
let plaintext = cipher.decrypt(&text.to_be_bytes())?;
|
||||
let output = output_format.unwrap_or_default().to_string(&plaintext);
|
||||
println!("{output}");
|
||||
Algorithm::Aes => {
|
||||
let key = Block128::from_str(&key)?;
|
||||
let text = Block128::from_str(&text)?;
|
||||
let cipher = Aes::from_key(&key.to_be_bytes());
|
||||
execute_cipher(operation, &cipher, &text.to_be_bytes(), output_format)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_cipher(
|
||||
operation: OperationChoice,
|
||||
cipher: &impl BlockCipher,
|
||||
text_bytes: &[u8],
|
||||
output_format: Option<OutputFormat>,
|
||||
) -> Result<()> {
|
||||
match operation {
|
||||
OperationChoice::Encrypt => {
|
||||
let ciphertext = cipher.encrypt(text_bytes)?;
|
||||
println!("{ciphertext:X}");
|
||||
}
|
||||
OperationChoice::Decrypt => {
|
||||
let plaintext = cipher.decrypt(text_bytes)?;
|
||||
let output = output_format.unwrap_or_default().to_string(&plaintext);
|
||||
println!("{output}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user