Skip to content

Commit

Permalink
支持aes_cbc加密算法
Browse files Browse the repository at this point in the history
  • Loading branch information
vnt-dev committed Aug 28, 2023
1 parent c336848 commit b9fe5e0
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 112 deletions.
6 changes: 5 additions & 1 deletion vnt-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use tokio::signal;
use tokio::signal::unix::{signal, SignalKind};

use common::args_parse::{ips_parse, out_ips_parse};
use vnt::cipher::CipherModel;
use vnt::core::{Config, Vnt, VntUtil};
use vnt::handle::handshake_handler::HandshakeEnum;
use vnt::handle::registration_handler::ReqEnum;
Expand Down Expand Up @@ -50,6 +51,7 @@ fn main() {
opts.optflag("", "relay", "仅使用服务器转发");
opts.optopt("", "par", "任务并行度(必须为正整数)", "<parallel>");
opts.optopt("", "thread", "线程数(必须为正整数)", "<thread>");
opts.optopt("", "model", "加密模式", "<model>");
//"后台运行时,查看其他设备列表"
opts.optflag("", "list", "后台运行时,查看其他设备列表");
opts.optflag("", "all", "后台运行时,查看其他设备完整信息");
Expand Down Expand Up @@ -201,6 +203,7 @@ fn main() {
return;
}
let thread_num = matches.opt_get::<usize>("thread").unwrap().unwrap_or(std::thread::available_parallelism().unwrap().get() * 2);
let cipher_model = matches.opt_get::<CipherModel>("model").unwrap().unwrap_or(CipherModel::AesGcm);
if thread_num == 0 {
println!("--thread invalid");
return;
Expand All @@ -211,7 +214,7 @@ fn main() {
server_address, server_address_str,
stun_server, in_ip,
out_ip, password, simulate_multicast, mtu,
tcp_channel, virtual_ip, relay, server_encrypt, parallel);
tcp_channel, virtual_ip, relay, server_encrypt, parallel, cipher_model);
let runtime = tokio::runtime::Builder::new_multi_thread().enable_all().worker_threads(thread_num).build().unwrap();
runtime.block_on(main0(config, !unused_cmd));
std::process::exit(0);
Expand Down Expand Up @@ -454,6 +457,7 @@ fn print_usage(program: &str, _opts: Options) {
println!(" --relay 仅使用服务器转发,不使用p2p,默认情况允许使用p2p");
println!(" --par <parallel> 任务并行度(必须为正整数),默认值为1");
println!(" --thread <thread> 线程数(必须为正整数),默认为核心数乘2");
println!(" --model <model> 加密模式,可选值 aes_gcm/aes_cbc,默认使用aes_gcm,通常情况使用aes_cbc性能更好");
println!();
println!(" --list {}", yellow("后台运行时,查看其他设备列表".to_string()));
println!(" --all {}", yellow("后台运行时,查看其他设备完整信息".to_string()));
Expand Down
3 changes: 2 additions & 1 deletion vnt-jni/src/vnt_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use jni::objects::{JClass, JObject, JString, JValue};
use jni::sys::jboolean;
use jni::sys::{jint, jlong, jobject};
use jni::JNIEnv;
use vnt::cipher::CipherModel;
use vnt::core::Config;
use vnt::core::sync::VntUtilSync;
use vnt::handle::registration_handler::{RegResponse, ReqEnum};
Expand Down Expand Up @@ -80,7 +81,7 @@ fn new_sync(env: &mut JNIEnv, config: JObject) -> Result<VntUtilSync, Error> {
token, device_id, name,
server_address, server_address_str,
stun_server, vec![],
vec![], password, false, None, false, None, false,false,1);
vec![], password, false, None, false, None, false,false,1,CipherModel::AesGcm);
match VntUtilSync::new(config) {
Ok(vnt_util) => {
Ok(vnt_util)
Expand Down
2 changes: 2 additions & 0 deletions vnt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ socket2 ={ version = "0.5.2", features = ["all"] }
tokio = { version = "1.28.1", features = ["full"] }
aes-gcm = {version="0.10.2", optional = true}
ring = {version="0.16.20", optional = true}
cbc = "0.1.2"
aes = "0.8.3"
stun-format = {version="1.0.1",features=["fmt","rfc3489"]}
rsa = {version="0.7.2", features = [] }
spki = {version="0.6.0",features=["fingerprint","alloc"]}
Expand Down
93 changes: 0 additions & 93 deletions vnt/src/cipher/aes_c.rs

This file was deleted.

128 changes: 128 additions & 0 deletions vnt/src/cipher/aes_cbc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use std::io;

use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
use rand::RngCore;

use crate::cipher::Finger;
use crate::protocol::body::AesCbcSecretBody;
use crate::protocol::{HEAD_LEN, NetPacket};

type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;

#[derive(Clone)]
pub struct AesCbcCipher {
pub(crate) cipher: AesCbcEnum,
pub(crate) finger: Finger,
}

#[derive(Clone)]
pub enum AesCbcEnum {
AES128CBC([u8; 16]),
AES256CBC([u8; 32]),
}

impl AesCbcCipher {
pub fn key(&self) -> &[u8] {
match &self.cipher {
AesCbcEnum::AES128CBC(key) => { key }
AesCbcEnum::AES256CBC(key) => { key }
}
}
}

impl AesCbcCipher {
pub fn new_128(key: [u8; 16], finger: Finger) -> Self {
Self {
cipher: AesCbcEnum::AES128CBC(key),
finger,
}
}
pub fn new_256(key: [u8; 32], finger: Finger) -> Self {
Self {
cipher: AesCbcEnum::AES256CBC(key),
finger,
}
}

pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
if !net_packet.is_encrypt() {
//未加密的数据直接丢弃
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
}
if net_packet.payload().len() < 12 + 16 {
log::error!("数据异常,长度{}小于{}",net_packet.payload().len(),12+16);
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
}
let mut iv = [0; 16];
iv[0..4].copy_from_slice(&net_packet.source().octets());
iv[4..8].copy_from_slice(&net_packet.destination().octets());
iv[8] = net_packet.protocol().into();
iv[9] = net_packet.transport_protocol();
iv[10] = net_packet.is_gateway() as u8;
iv[11] = net_packet.source_ttl();
iv[12..16].copy_from_slice(&self.finger.hash[0..4]);

let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut())?;
let finger = self.finger.calculate_finger(&iv[..12], secret_body.en_body());
if &finger != secret_body.finger() {
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
}
let rs = match &self.cipher {
AesCbcEnum::AES128CBC(key) => { Aes128CbcDec::new(&(*key).into(), &iv.into()).decrypt_padded_mut::<Pkcs7>(secret_body.en_body_mut()) }
AesCbcEnum::AES256CBC(key) => { Aes256CbcDec::new(&(*key).into(), &iv.into()).decrypt_padded_mut::<Pkcs7>(secret_body.en_body_mut()) }
};
match rs {
Ok(buf) => {
let len = buf.len();
net_packet.set_encrypt_flag(false);
//减去末尾的随机数
net_packet.set_data_len(HEAD_LEN + len - 4)?;
Ok(())
}
Err(e) => {
Err(io::Error::new(io::ErrorKind::Other, format!("解密失败:{}", e)))
}
}
}
/// net_packet 必须预留足够长度
/// data_len是有效载荷的长度
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
let mut iv = [0; 16];
iv[0..4].copy_from_slice(&net_packet.source().octets());
iv[4..8].copy_from_slice(&net_packet.destination().octets());
iv[8] = net_packet.protocol().into();
iv[9] = net_packet.transport_protocol();
iv[10] = net_packet.is_gateway() as u8;
iv[11] = net_packet.source_ttl();
iv[12..16].copy_from_slice(&self.finger.hash[0..4]);
//先扩充随机数
let data_len = net_packet.data_len();
net_packet.set_data_len(data_len + 16)?;
let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut())?;
secret_body.set_random(rand::thread_rng().next_u32());
let p_len = secret_body.en_body().len();
net_packet.set_data_len_max();
let rs = match &self.cipher {
AesCbcEnum::AES128CBC(key) => { Aes128CbcEnc::new(&(*key).into(), &iv.into()).encrypt_padded_mut::<Pkcs7>(net_packet.payload_mut(), p_len) }
AesCbcEnum::AES256CBC(key) => { Aes256CbcEnc::new(&(*key).into(), &iv.into()).encrypt_padded_mut::<Pkcs7>(net_packet.payload_mut(), p_len) }
};
return match rs {
Ok(buf) => {
let len = buf.len();
let finger = self.finger.calculate_finger(&iv[..12], buf);
//设置实际长度
net_packet.set_data_len(HEAD_LEN + len + finger.len())?;
let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut())?;
secret_body.set_finger(&finger)?;
net_packet.set_encrypt_flag(true);
Ok(())
}
Err(e) => {
Err(io::Error::new(io::ErrorKind::Other, format!("加密失败:{}", e)))
}
};
}
}
Loading

0 comments on commit b9fe5e0

Please sign in to comment.