1use aes::cipher::{Block, BlockEncrypt, KeyInit};
2use aes::Aes128;
3use clap::{arg, Parser};
4use eyre::Result;
5use rand::{rng, Rng};
6use sha2::{Digest, Sha512};
7
8use kabu_types_entities::KeyStore;
9
10const BLOCK_SIZE: usize = 16;
11
12#[derive(Parser, Debug)]
13enum Commands {
14 GeneratePassword,
15 Encrypt {
16 #[arg(short, long)]
17 key: String,
18 },
19}
20
21fn encrypt_key(private_key: Vec<u8>, pwd: Vec<u8>) -> Vec<u8> {
22 let mut hasher = Sha512::new();
23 hasher.update(pwd.clone());
24 let pwd_hash = hasher.finalize();
25
26 let cipher = Aes128::new_from_slice(&pwd_hash[0..16]).unwrap();
27
28 let mut ret = Vec::new();
29 let mut block: Block<Aes128> = [0u8; BLOCK_SIZE].into();
30
31 let mut a = 0;
32 while a + BLOCK_SIZE <= private_key.len() {
33 block.copy_from_slice(&private_key[a..a + BLOCK_SIZE]);
34 cipher.encrypt_block(&mut block);
35 ret.extend_from_slice(&block);
36 a += BLOCK_SIZE;
37 }
38
39 let mut sha = Sha512::new();
40 sha.update(&private_key);
41 let crc = &sha.finalize()[0..4];
42
43 ret.extend(crc);
44 ret
45}
46
47fn main() -> Result<()> {
48 let args = Commands::parse();
49 match args {
50 Commands::GeneratePassword => {
51 let mut rng = rng();
52 let pwd: Vec<u8> = (0..BLOCK_SIZE).map(|_| rng.random::<u8>()).collect();
53 println!("{pwd:?}");
54 }
55 Commands::Encrypt { key } => {
56 let pwd = kabu_types_entities::private::KEY_ENCRYPTION_PWD.to_vec();
57
58 let private_key = hex::decode(key.strip_prefix("0x").unwrap_or(key.clone().as_str()))?;
59 let encrypted_key = encrypt_key(private_key.clone(), pwd.clone());
60 let keystore = KeyStore::new_from_bytes(pwd);
61 let decrypted_key = keystore.encrypt_once(&encrypted_key.to_vec())?;
62 if decrypted_key == private_key {
63 println!("Encrypted private key : {}", hex::encode(encrypted_key))
64 } else {
65 println!("Error encrypting private key");
66 }
67 }
68 }
69
70 Ok(())
71}