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
use bytes::{BufMut, Bytes};
use super::qqtea_encrypt;
use crate::binary::BinaryWriter;
use crate::hex::decode_hex;
use p256::{ecdh::EphemeralSecret, EncodedPoint, PublicKey};
pub trait IEncryptMethod {
fn id(&self) -> u8;
fn do_encrypt(&self, data: &[u8], key: &[u8]) -> Vec<u8>;
}
#[derive(Debug)]
pub struct EncryptECDH {
pub initial_share_key: Bytes,
pub public_key: Bytes,
pub public_key_ver: u16,
}
impl Default for EncryptECDH {
fn default() -> Self {
let mut ecdh = EncryptECDH {
initial_share_key: Bytes::new(),
public_key: Bytes::new(),
public_key_ver: 1,
};
ecdh.generate_key("04EBCA94D733E399B2DB96EACDD3F69A8BB0F74224E2B44E3357812211D2E62EFBC91BB553098E25E33A799ADC7F76FEB208DA7C6522CDB0719A305180CC54A82E");
ecdh
}
}
impl EncryptECDH {
pub fn generate_key(&mut self, s_pub_key: &str) {
let s_pub_key = decode_hex(s_pub_key).expect("failed to decode ecdh hex"); let secret = EphemeralSecret::random(rand::thread_rng()); let pub_key = PublicKey::from_sec1_bytes(&s_pub_key).expect("failed to get s_pub_key"); let share = secret.diffie_hellman(&pub_key); let share_x = &share.as_bytes()[0..16];
self.initial_share_key = Bytes::copy_from_slice(&md5::compute(share_x).0);
let self_public_key = secret.public_key();
let point = EncodedPoint::from(self_public_key);
self.public_key = Bytes::copy_from_slice(point.as_bytes());
}
}
impl IEncryptMethod for EncryptECDH {
fn id(&self) -> u8 {
0x87
}
fn do_encrypt(&self, data: &[u8], key: &[u8]) -> Vec<u8> {
let mut w = Vec::new();
w.put_u8(0x02);
w.put_u8(0x01);
w.put_slice(key);
w.put_u16(0x01_31);
w.put_u16(self.public_key_ver);
w.put_u16(self.public_key.len() as u16);
w.put_slice(&self.public_key);
w.encrypt_and_write(&self.initial_share_key, data);
w
}
}
pub struct EncryptSession {
t133: Vec<u8>,
}
impl EncryptSession {
pub fn new(t133: &[u8]) -> EncryptSession {
EncryptSession {
t133: t133.to_vec(),
}
}
}
impl IEncryptMethod for EncryptSession {
fn id(&self) -> u8 {
69
}
fn do_encrypt(&self, data: &[u8], key: &[u8]) -> Vec<u8> {
let encrypt = qqtea_encrypt(data, key);
let mut w = Vec::new();
w.put_u16(self.t133.len() as u16);
w.put_slice(&self.t133);
w.put_slice(&encrypt);
w
}
}
#[cfg(test)]
mod tests {
use crate::crypto::EncryptECDH;
#[test]
fn test_ecdh_generate_key() {
let mut e = EncryptECDH::default();
e.generate_key("04EBCA94D733E399B2DB96EACDD3F69A8BB0F74224E2B44E3357812211D2E62EFBC91BB553098E25E33A799ADC7F76FEB208DA7C6522CDB0719A305180CC54A82E");
println!("{:?}", e.initial_share_key);
println!("{:?}", e.public_key);
}
}