azalea_crypto/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod signing;
4
5use aes::cipher::inout::InOutBuf;
6use aes::{
7    cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit},
8    Aes128,
9};
10use rand::{rngs::OsRng, RngCore};
11use sha1::{Digest, Sha1};
12pub use signing::*;
13
14fn generate_secret_key() -> [u8; 16] {
15    let mut key = [0u8; 16];
16    OsRng.fill_bytes(&mut key);
17    key
18}
19
20pub fn digest_data(server_id: &[u8], public_key: &[u8], private_key: &[u8]) -> Vec<u8> {
21    let mut digest = Sha1::new();
22    digest.update(server_id);
23    digest.update(private_key);
24    digest.update(public_key);
25    digest.finalize().to_vec()
26}
27
28pub fn hex_digest(digest: &[u8]) -> String {
29    // Note that the Sha1.hexdigest() method used by minecraft is non standard.
30    // It doesn't match the digest method found in most programming languages
31    // and libraries. It works by treating the sha1 output bytes as one large
32    // integer in two's complement and then printing the integer in base 16,
33    // placing a minus sign if the interpreted number is negative.
34
35    num_bigint::BigInt::from_signed_bytes_be(digest).to_str_radix(16)
36}
37
38#[derive(Debug)]
39pub struct EncryptResult {
40    pub secret_key: [u8; 16],
41    pub encrypted_public_key: Vec<u8>,
42    pub encrypted_challenge: Vec<u8>,
43}
44
45pub fn encrypt(public_key: &[u8], challenge: &[u8]) -> Result<EncryptResult, String> {
46    // On receipt of a Encryption Request from the server, the client will
47    // generate a random 16-byte shared secret, to be used with the AES/CFB8
48    // stream cipher.
49    let secret_key = generate_secret_key();
50    // let hash = hex_digest(&digest_data(server_id.as_bytes(), public_key,
51    // &secret_key));
52
53    // this.keybytes = Crypt.encryptUsingKey(publicKey, secretKey.getEncoded());
54    // this.challenge = Crypt.encryptUsingKey(publicKey, arrby);
55    let encrypted_public_key: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, &secret_key)?;
56    let encrypted_challenge: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, challenge)?;
57
58    Ok(EncryptResult {
59        secret_key,
60        encrypted_public_key,
61        encrypted_challenge,
62    })
63}
64
65pub type Aes128CfbEnc = cfb8::Encryptor<Aes128>;
66pub type Aes128CfbDec = cfb8::Decryptor<Aes128>;
67
68pub fn create_cipher(key: &[u8]) -> (Aes128CfbEnc, Aes128CfbDec) {
69    (
70        Aes128CfbEnc::new_from_slices(key, key).unwrap(),
71        Aes128CfbDec::new_from_slices(key, key).unwrap(),
72    )
73}
74
75pub fn encrypt_packet(cipher: &mut Aes128CfbEnc, packet: &mut [u8]) {
76    let (chunks, rest) = InOutBuf::from(packet).into_chunks();
77    assert!(rest.is_empty());
78    cipher.encrypt_blocks_inout_mut(chunks);
79}
80pub fn decrypt_packet(cipher: &mut Aes128CfbDec, packet: &mut [u8]) {
81    let (chunks, rest) = InOutBuf::from(packet).into_chunks();
82    assert!(rest.is_empty());
83    cipher.decrypt_blocks_inout_mut(chunks);
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_generate_secret_key() {
92        let key = generate_secret_key();
93        assert_eq!(key.len(), 16);
94    }
95
96    #[test]
97    fn test_hex_digest() {
98        let digest = hex_digest(&digest_data(b"Notch", &[], &[]));
99        assert_eq!(digest, "4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48");
100
101        let digest = hex_digest(&digest_data(b"jeb_", &[], &[]));
102        assert_eq!(digest, "-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1");
103
104        let digest = hex_digest(&digest_data(b"simon", &[], &[]));
105        assert_eq!(digest, "88e16a1019277b15d58faf0541e11910eb756f6");
106    }
107
108    #[test]
109    fn encode_packet_twice() {
110        let mut packet = vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
111        let (mut enc_cipher, _dec_cipher) = create_cipher(b"1234567890123456");
112        encrypt_packet(&mut enc_cipher, &mut packet);
113        assert_eq!(packet, vec![117, 151, 183, 45, 229, 232, 43, 181, 121, 16]);
114        let mut packet = vec![0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13];
115        encrypt_packet(&mut enc_cipher, &mut packet);
116        assert_eq!(
117            packet,
118            vec![185, 223, 129, 153, 173, 140, 133, 239, 59, 168]
119        );
120    }
121
122    #[test]
123    fn encode_packet_long() {
124        let mut packet = (0..=255).collect::<Vec<u8>>();
125        let (mut enc_cipher, _dec_cipher) = create_cipher(b"1234567890123456");
126        encrypt_packet(&mut enc_cipher, &mut packet);
127        assert_eq!(
128            packet,
129            vec![
130                117, 151, 183, 45, 229, 232, 43, 181, 121, 16, 185, 223, 129, 153, 173, 140, 133,
131                239, 59, 168, 148, 39, 97, 19, 22, 219, 78, 70, 116, 143, 21, 223, 155, 99, 201,
132                62, 133, 77, 244, 152, 254, 36, 135, 147, 45, 25, 66, 236, 2, 12, 101, 39, 140, 62,
133                7, 57, 19, 101, 217, 91, 142, 243, 0, 3, 100, 142, 160, 21, 219, 145, 151, 37, 11,
134                30, 190, 176, 26, 90, 143, 63, 255, 188, 254, 40, 41, 92, 163, 197, 8, 8, 111, 175,
135                49, 234, 82, 34, 5, 96, 162, 7, 217, 42, 77, 38, 127, 213, 207, 251, 34, 173, 34,
136                132, 23, 12, 118, 59, 51, 216, 173, 199, 137, 95, 132, 222, 243, 195, 81, 60, 205,
137                52, 65, 209, 125, 137, 5, 52, 219, 165, 248, 35, 173, 57, 200, 182, 162, 148, 70,
138                62, 102, 21, 220, 158, 71, 98, 47, 231, 196, 58, 8, 70, 160, 177, 159, 50, 20, 187,
139                31, 249, 68, 26, 142, 171, 239, 193, 10, 174, 14, 80, 238, 114, 124, 185, 253, 246,
140                47, 67, 37, 69, 70, 9, 69, 135, 13, 195, 253, 8, 241, 175, 170, 75, 231, 7, 92, 18,
141                38, 132, 65, 146, 202, 130, 238, 224, 30, 113, 168, 241, 159, 131, 238, 67, 1, 244,
142                74, 172, 86, 95, 192, 236, 198, 188, 81, 67, 49, 230, 166, 52, 224, 238, 11, 252,
143                0, 179, 56, 209, 231, 62, 146, 106, 18, 217, 138, 89, 110, 240, 255, 192
144            ]
145        );
146    }
147
148    #[test]
149    fn encode_decode_packet() {
150        let mut packet = vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
151        let (mut enc_cipher, mut dec_cipher) = create_cipher(b"1234567890123456");
152        encrypt_packet(&mut enc_cipher, &mut packet);
153        decrypt_packet(&mut dec_cipher, &mut packet);
154        assert_eq!(
155            packet,
156            vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]
157        );
158    }
159}