From: kmeaw
Date: 2025-09-02 19:36:55Z
А что именно заняло больше всего времени и вызвало больше всего трудностей?
Я сделал cargo search aes, взял первый попавшийся crate, скопировал пример и
чуть подправил его. Затем попытался скормить результат в openssl enc -d
-aes128, и только тогда понял, что забыл про cipher modes и IV.
После этого сделал cargo search cbc и почитал другой пример, а потом исправлял
ошибки компиляции, подгоняя типы.
Получилось вот так:
[nix-shell:/tmp/sgaes]$ ( cat src/main.rs ; head -c 16 /dev/zero ) |
> cargo run 11223344556677881122334455667788 00000000000000000000000000000000 |
> openssl enc -d -aes128 -nosalt -K 11223344556677881122334455667788 -iv 00000000000000000000000000000000 -nopad
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/sgaes 11223344556677881122334455667788 00000000000000000000000000000000`
use aes::Aes128;
use aes::cipher::{BlockEncryptMut, KeyIvInit, generic_array::GenericArray};
use cbc;
use hex;
use std::env;
use std::io;
use std::io::{Read, Write};
type Aes128CbcEnc = cbc::Encryptor<Aes128>;
fn main() {
let args: Vec<String> = env::args().collect();
let hexkey = args
.get(1)
.unwrap_or_else(|| panic!("pass 128 bit hex key and iv in args"));
let hexiv = args
.get(2)
.unwrap_or_else(|| panic!("pass 128 bit hex key and iv in args"));
let key = hex::decode(hexkey).unwrap_or_else(|_| panic!("bad key hex"));
let key: [u8; 16] = key.try_into().unwrap_or_else(|_| panic!("bad key len"));
let iv = hex::decode(hexiv).unwrap_or_else(|_| panic!("bad iv hex"));
let iv: [u8; 16] = iv.try_into().unwrap_or_else(|_| panic!("bad iv len"));
let mut input = io::stdin().lock();
let mut output = io::stdout().lock();
let key = GenericArray::from(key);
let mut block = GenericArray::from([42u8; 16]);
let mut cipher = Aes128CbcEnc::new(&key.into(), &iv.into());
while let Ok(_) = input.read_exact(&mut block) {
cipher.encrypt_block_mut(&mut block);
output.write_all(&block).expect("cannot write");
}
}
From: Sergey Matveev
Date: 2025-09-02 19:56:32Z
*** kmeaw@kmeaw.com [2025-09-02 19:37]:
>А что именно заняло больше всего времени и вызвало больше всего трудностей?
Было давно, уже не вспомню, совсем. Кода не осталось.
Никаких "cbc" я внешних точно не собирался использовать, а делать это
руками. Помню, что при каждом действии он ругался что "не могу
скомпилировать", говно я какое-то написал. Читаешь про типы, синтаксис,
все эти ownership (у меня не только main функа была). Видимо я
принципиально не понимал многого. В итоге я так и не смог написать
работающее приложение.
Может быть мне не хватило ещё одного дня повозиться? Может быть, не
знаю. Я точно не знаю, но когда-то немного трогав Erlang, я за неделю уж
точно бы смог написать такую программу на нём. Это просто пример
ЯП/инструмента, довольно сильно отличающегося от "штатного" моего стэка.
Но когда я за неделю не смог осилить инструмент, чтобы написать
простейшую программу -- для меня это перебор. Может нужно бы было
какую-то особую книжку почитать по Rust? Но почему для многих других
языков достаточно только их документации (к ней и tutorial на офсайтах
тоже могу отнести)?
Я помню что принципиально себе тогда поставил условие: под рукой только
иметь документацию и не смотреть ни в чужой код, ни в код библиотек.
Само собой за пять минут я бы быстро мог найти пример кода выполняющего
работу с AES, с CBC, сделал бы copy-paste, нашёл код для работы с hex и
argv, и через полчаса бы у меня была работающая программа. И когда я
сдался, то я всё же пошёл смотреть как работают с AES/whatever в других
местах и оно всё выглядело понятно как и в этом комментарии вы написали.
Но я не смог допереть всего этого самостоятельно. Там было много (взял
из 34c103d1b115de3e2f05b5eb4b31dbe2b34bb78a) такого (это полушутка):
impl I<Don't> {
fn know<'a, How::Someone>(could: &'a Say) -> This<'a>
with A: Straight<Face> + Send + Sync + 'a
где я не понимал бы что значит та или иная кавычка, скобочки всякие и
прочее. Я видел бы, что они (вроде) делают что мне надо, но без
понимания почему именно так, а не иначе написано.