1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
use byteorder::WriteBytesExt; use crypto::{ buffer::{ReadBuffer, WriteBuffer}, digest::Digest, }; pub trait Encrypt { fn ekey(&self) -> crate::EResult<String>; } fn encode_id_util( id: u64, sub_key: &str, secret_key: &str, secret_key_bytes: &[u8], ) -> crate::EResult<String> { let version: u32 = 1; let crc: u32 = crc::crc32::checksum_ieee(id.to_string().as_bytes()); let mut msg: Vec<u8> = vec![]; msg.write_u32::<byteorder::LittleEndian>(crc)?; msg.write_u64::<byteorder::LittleEndian>(id)?; msg.write_u32::<byteorder::LittleEndian>(version)?; let mut sha_value = crypto::sha2::Sha256::new(); sha_value.input_str(&format!("{}{}", secret_key, sub_key)); let mut iv: Vec<u8> = vec![0; 32]; sha_value.result(&mut iv); let iv = &iv[..16]; let mut encryptor = crypto::aes::cbc_encryptor( crypto::aes::KeySize::KeySize256, &secret_key_bytes[..32], iv, crypto::blockmodes::NoPadding, ); let mut final_result = Vec::<u8>::new(); let mut read_buffer = crypto::buffer::RefReadBuffer::new(msg.as_ref()); let mut buffer = [0; 16]; let mut write_buffer = crypto::buffer::RefWriteBuffer::new(&mut buffer); loop { let result = encryptor.encrypt(&mut read_buffer, &mut write_buffer, true); let result = match result { Ok(v) => v, Err(e) => return Err(crate::EError::Encrypt(e).into()), }; final_result.extend( write_buffer .take_read_buffer() .take_remaining() .iter() .copied(), ); match result { crypto::buffer::BufferResult::BufferUnderflow => break, crypto::buffer::BufferResult::BufferOverflow => {} } } Ok(base64::encode_config(&final_result, base64::URL_SAFE).replace("=", "")) } #[deprecated(since = "0.1.5", note = "Please use .encrypt() instead")] pub fn encode( id: u64, sub_key: &str, ) -> crate::EResult<String> { encrypt(id, sub_key) } pub fn encrypt( id: u64, sub_key: &str, ) -> crate::EResult<String> { let config = crate::CONFIG.read().unwrap(); if config.secret_key.is_none() { return Err(crate::EError::SecretKeyNotFound.into()); } encode_id_util( id, sub_key, config.secret_key.as_ref().unwrap(), config.secret_key_bytes.as_ref(), ) } #[deprecated( since = "0.1.5", note = "Please use .encrypt_with_secret() instead" )] pub fn encode_with_secret( id: u64, sub_key: &str, secret: &str, ) -> crate::EResult<String> { encrypt_with_secret(id, sub_key, secret) } pub fn encrypt_with_secret( id: u64, sub_key: &str, secret: &str, ) -> crate::EResult<String> { encode_id_util(id, sub_key, secret, secret.as_bytes().as_ref()) }