Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/kerberos/crypto/des3_cbc_sha1.rb
Views: 11766
# -*- coding: binary -*-1require 'rex/text'23module Rex4module Proto5module Kerberos6module Crypto7class Des3CbcSha1 < BlockCipherBase8include Rex::Proto::Kerberos::Crypto::Asn1Utils9SEED_SIZE = 2110BLOCK_SIZE = 811PADDING_SIZE = 812MAC_SIZE = 2013HASH_FUNCTION = 'SHA1'1415# Derive an encryption key based on a password and salt for the given cipher type16#17# @param string [Stringl The password to use as the basis for key generation18# @param salt [String] A salt (usually based on domain and username)19# @param params [String] Unused for this encryption type20# @return [String] The derived key21def string_to_key(string, salt, params: nil)22raise Rex::Proto::Kerberos::Model::Error::KerberosError, 'Params not supported for DES' unless params == nil23utf8_encoded = (string + salt).encode('UTF-8').bytes24k = random_to_key(nfold(utf8_encoded, 21))25k = k.pack('C*')26result = derive(k, 'kerberos'.encode('UTF-8'))2728result29end3031def decrypt_asn1(ciphertext, key, msg_type)32result = decrypt(ciphertext, key, msg_type)33padding_removed = truncate_nulls_after_asn1(result)34end3536private3738# Decrypts the cipher using DES3-CBC-SHA1 schema39def decrypt_basic(ciphertext, key)40raise Rex::Proto::Kerberos::Model::Error::KerberosError, 'Ciphertext is not a multiple of block length' unless ciphertext.length % BLOCK_SIZE == 04142cipher = OpenSSL::Cipher.new('des-ede3-cbc')43if key.length != cipher.key_len44raise Rex::Proto::Kerberos::Model::Error::KerberosError, "Decryption key length must be #{cipher.key_len} for des-ede3-cbc"45end46cipher.decrypt47cipher.key = key48cipher.padding = 049decrypted = cipher.update(ciphertext) + cipher.final5051decrypted52end5354# Encrypts the cipher using DES3-CBC-SHA1 schema55def encrypt_basic(plaintext, key)56cipher = OpenSSL::Cipher.new('des-ede3-cbc')57if key.length != cipher.key_len58raise Rex::Proto::Kerberos::Model::Error::KerberosError, "Encryption key length must be #{cipher.key_len} for des-ede3-cbc"59end60cipher.encrypt61cipher.key = key62cipher.padding = 063encrypted = cipher.update(plaintext) + cipher.final6465encrypted66end6768def random_to_key(seed)69def expand(seed)70def parity(b)71# Return b with the low-order bit set to yield odd parity.72b &= ~173b | (b.digits(2).count(1) + 1) % 274end7576raise Rex::Proto::Kerberos::Model::Error::KerberosError unless seed.length == 77778firstbytes = seed.map {|b| parity(b & ~1)}79tmp = 7.times.map { |i| (seed[i] & 1) << i+1 }80lastbyte = parity(tmp.sum)81keybytes = firstbytes + [lastbyte]82if _is_weak_des_key(keybytes)83keybytes[7] = keybytes[7] ^ 0xF084end8586keybytes87end8889raise Rex::Proto::Kerberos::Model::Error::KerberosError unless seed.length == 219091subkeys = seed.each_slice(7).map { |slice| expand(slice) }92subkeys.flatten93end94end95end96end97end98end99100101