[{"data":1,"prerenderedAt":75},["ShallowReactive",2],{"article-12":3},{"id":4,"title":5,"body":6,"create":62,"description":63,"extension":64,"labels":65,"locked":67,"meta":68,"navigation":69,"path":70,"seo":71,"stem":72,"update":73,"__hash__":74},"articles/article/12.md","rust 实现文件加解密",{"type":7,"value":8,"toc":59},"minimark",[9,28,31,41,44,52],[10,11,12,13,17,18,21,22,24,25,27],"p",{},"本方法使用了 ",[14,15,16],"code",{},"aes-gcm","  与 ",[14,19,20],{},"pbkdf2"," 库，其中 ",[14,23,16],{},"  用来加密文件， ",[14,26,20],{}," 用来生成加密密钥",[10,29,30],{},"附上整个文件加解密类的实现代码：\n依赖：",[32,33,39],"pre",{"className":34,"code":36,"language":37,"meta":38},[35],"language-toml","aes-gcm = \"0.10\"\npbkdf2 = { version = \"0.12\", features = [\"simple\"] }\nsha2 = \"0.10.8\"\n","toml","",[14,40,36],{"__ignoreMap":38},[10,42,43],{},"代码：",[32,45,50],{"className":46,"code":48,"language":49,"meta":38},[47],"language-rs","pub struct FileEncryption\u003C'cipher> {\n  password: &'cipher str,\n  rounds: u32,\n}\n\nimpl\u003C'cipher> FileEncryption\u003C'cipher> {\n  pub fn new(password: &'cipher str, rounds: u32) -> Self {\n    FileEncryption {\n      password,\n      rounds,\n    }\n  }\n\n  fn create_password(&self, file_name: &str) -> Result\u003C[u8; 32]> {\n    let salt = file_name.as_bytes();\n    let password = self.password.as_bytes();\n    let mut key = [0u8; 32];\n    pbkdf2_hmac::\u003CSha256>(password, salt, self.rounds, &mut key);\n    Ok(key)\n  }\n\n  fn generate_cipher_and_nonce(&self, file_name: &str)\n                               -> Result\u003C(AesGcm\u003CAes256, U12>, GenericArray\u003Cu8, U12>)> {\n    let key = self.create_password(file_name)?;\n    let key = Key::\u003CAes256Gcm>::from(key);\n    let cipher = Aes256Gcm::new(&key);\n    let mut nonce = Nonce::default();\n    pbkdf2_hmac::\u003CSha256>(file_name.as_bytes(), self.password.as_bytes(), self.rounds, &mut nonce);\n    Ok((cipher, nonce))\n  }\n\n  pub fn encrypt_file(&self, file_path: &Path) -> Result\u003CPathBuf> {\n    let file_name = file_path.file_name().ok_or(anyhow!(CANNOT_READ_FILE_NAME))?\n      .to_str().ok_or(anyhow!(CONVERT_STR_FAIL))?;\n    let (cipher, nonce) =\n      self.generate_cipher_and_nonce(file_name)?;\n    let mut input_file = File::open(file_path)?;\n    let mut buffer = Vec::new();\n    input_file.read_to_end(&mut buffer)?;\n    let ciphertext = cipher.encrypt(&nonce, &*buffer);\n    if let Err(e) = ciphertext {\n      anyhow!(e);\n    };\n    let ciphertext = ciphertext.unwrap();\n    let save_path = PathBuf::new().join(TEMP_PATH)\n      .join(format!(\"{}{}\", file_name, ENCRYPTED_FILE_SUFFIX));\n    let mut output_file = File::create(&save_path)?;\n    output_file.write_all(&*ciphertext)?;\n    Ok(save_path)\n  }\n\n  pub fn decrypt_file(&self, file_path: &Path) -> Result\u003CPathBuf> {\n    let file_name = file_path.file_name().ok_or(anyhow!(CANNOT_READ_FILE_NAME))?\n      .to_str().ok_or(anyhow!(CONVERT_STR_FAIL))?.replace(ENCRYPTED_FILE_SUFFIX, \"\");\n    let (cipher, nonce) = self.generate_cipher_and_nonce(&*file_name)?;\n    let mut input_file = File::open(file_path)?;\n    let mut buffer = Vec::new();\n    input_file.read_to_end(&mut buffer)?;\n    let ciphertext = cipher.decrypt(&nonce, &*buffer);\n    if let Err(e) = ciphertext {\n      anyhow!(e);\n    };\n    let ciphertext = ciphertext.unwrap();\n    let save_path = PathBuf::new().join(TEMP_PATH).join(file_name);\n    let mut output_file = File::create(&save_path)?;\n    output_file.write_all(&*ciphertext)?;\n    Ok(save_path)\n  }\n}\n","rs",[14,51,48],{"__ignoreMap":38},[10,53,54,55,58],{},"大写的常量都是其他文件里定义的 ",[14,56,57],{},"&str"," 类型",{"title":38,"searchDepth":60,"depth":60,"links":61},2,[],"2024-06-09T04:01:28.000Z","本方法使用了 aes-gcm  与 pbkdf2 库，其中 aes-gcm  用来加密文件， pbkdf2 用来生成加密密钥","md",[66],"rust",false,{},true,"/article/12",{"title":5,"description":63},"article/12",null,"cnqlI7yoLYl86hM7kgG-pWxqlMkC-QAIxLaX3jhBQuI",1755235549197]