почему я получаю ошибку mac_bad_record с моей реализацией tls1.2 - PullRequest
0 голосов
/ 11 марта 2019

поэтому я пишу свою собственную реализацию tls 1.2 для изучения и потому, что сервер, к которому я подключаюсь, использует измененную версию протокола, которая все равно запрашивает неслучайный client_random (TL; DR: у меняошибка bad_record_mac в готовом сообщении с моей реализацией, и я не могу найти, где я допустил ошибку)

Мне нужно указать единственное, что меня беспокоит, это TLS_RSA_WITH_AES_128_CBC_SHA

, поэтому сначала я создаюМой клиент случайный, и рукопожатие начинается с отправки сервером server_random и открытого ключа RSA в сертификате

. Я генерирую случайный pre_master_secret и шифрую его открытым ключом RSA (выполняется собственным модулем языка, поэтомуне мешайте мне в этом) и отправьте его обратно в сообщении client_key_exchange

Затем я сгенерирую master_secret из: PRF (pre_master_secret, "master secret", client_random + server_random), где PRF:

class TlsMasterSecret {
    constructor(pre_master_secret, client_random, server_random) {
        this.master_secret = TlsMasterSecret.PRF(pre_master_secret, Buffer.from("master secret", "ascii"), Buffer.concat([client_random, server_random]), 48);
        this.master_secret = this.master_secret.slice(0, 48);
        this.key_block = TlsMasterSecret.PRF(this.master_secret, Buffer.from("key expansion", "ascii"),Buffer.concat([server_random, client_random]), 104);
        // 20 20 16 16
        this.client_write_MAC_key = this.key_block.slice(0, 20);
        this.server_write_MAC_key = this.key_block.slice(20, 40);
        this.client_write_key = this.key_block.slice(40, 56);
        this.server_write_key = this.key_block.slice(56, 72);
    }
    static PRF(secret, label, seed, neededLength) {
        return TlsMasterSecret.P_hash(secret, Buffer.concat([label, seed]), neededLength)
    }
    static P_hash(secret, seed, neededLength) {
        const A = [seed];
        let resultHash = Buffer.from("", "hex");
        // HMAC_SHA256 generates 32 bytes per update
        const iterations = Math.ceil(neededLength / 32);
        // generate A
        for(let i = 1; i < iterations + 1; i++) {
            A[i] = TlsMasterSecret.HMAC_hash(secret, A[i-1]);
        }
        // calculates the hash
        for(let i = 1; i < iterations + 1; i++) {
            resultHash = Buffer.concat([resultHash, TlsMasterSecret.HMAC_hash(secret, A[i])]);
        }
        return resultHash;
    }
    static HMAC_hash(secret, seed) {
        const hmac = crypto.createHmac("sha256", secret);
        hmac.update(seed);
        return hmac.digest();
    }
}

затем я создаю сообщение Finished от 0x1400000cd на 12 байтов verify_data

verify_data генерируется так:

// I strip the record layer headers off the messages
client_hello = 0x0100002f03032668f90d7d3b3420f7712a3004247d233d90cc63fb4b23f77912b31c8c89893b000008002f0035003c003d0100
server_hello = 0x0200002603031296263fba0a7955a83b2bf9c3716c8ee1c52e9065b89ee5649b31391d7ce84700002f00
certificate = 0b00034e00034b00034830820344308202ada00302.......
server_hello_done = 0e000000
client_key_exchange = 100000820080673f1772e35c7565a1e0c2fae5ee1b5bf92211ba9e4de14620f43856d954cf737aa04c48f8b2ffa182f652fedd68523056acda3c7cd101c5a2c3a625655df67ad9fb7ca082cf68476f174ea7b83eab980b7b15657036ad0e26883c9bfe368847a02b052817cb80dabafc6af1dac8064ea0dc676e0f8ea74f84a122135f31b612

handshake_messages = client_hello + server_hello + certificate + server_hello_done + client_key_exchange

verify_data = PRF(master_secret, "client finished", sha256(handshake_messages))[0..12]

, тогда я создаю MAC, который будет идти по этому сообщению:


// hmac_sha1(secret, seed)
// seq_num is a uint64 @ 0 for the first message, 0x00000000
// type = 0x16
// version = 0x0303
// length = 0x0010
// content = 0x1400000c + verify_data
MAC = hmac_sha1(client_write_MAC_key, seq_num + type + version + length + content)
plaintext = content + MAC

IV = randomBytes(16)

// aes_128_cbc(key, IV, message)
ciphertext = aes_128_cbc(client_write_key, IV, plaintext)

final = 0x16 + 0x0303 + 0x0040 + IV + ciphertext

, если выпрочитайте все это и все еще готовы помочь вам большое спасибо, я думаю, что я следовал спецификации, но я получаю ошибку bad_record_mac в wireshark, так что где-то что-то не так, я просто не могу найти это: (

...