def sendSentinel(self): """ State 1: Send sentinel Cookie : SESSSIONID=HandshakeID; ID=Tunnel_Tag HandshakeID = Sentinel+Nonce_Client """ self.rc4_handshake_c2d = RC4.RC4(self.session_key) self.rc4_handshake_d2c = RC4.RC4(self.session_key) self.rc4_tunnel = RC4.RC4(self.session_key) # Filler text # plain_text = const.HTTPU_CLIENTHELLO auth_plain_text = '%s%s%s' % (self.encoder.digest(plain_text), const.HTTPU_HASHSEP, plain_text) cipher_text = self.rc4_handshake_c2d.update(auth_plain_text) # HTTP Request # req = http_util.create_http_req(self, cipher_text, self.handshake_ID, self.tunnel_tag.encode("hex"), self.host_name) self.transport.write(req) # New state # self.state = const.STATE_3_UNI
def __rsa_key_exchange(self, data, metadata): if self.check_sid(self.s_sid): # XXX: The fact that the server session ID is in # the dictionary already is a really bad thing. # There should be no client key exchange message # if the client and server agree to resume. raise sslimBadValue("SID found with client key exchange") # XXX: The size of this is dependent upon the cipher suite chosen! # Section 7.4.7.1 of RFC5246 details what these bytes mean for # RSA authentication! if self.ver == self.SSLv3_0: if self.cipher_suite['key_exch'] != 'RSA': raise sslimUnknownCipher("SSLv3 not RSA key exchange") pms = data else: # The first two bytes are the length of the key. pms_len = int(struct.unpack('>H', data[:self.hs_pms_len_size])[0]) data = data[self.hs_pms_len_size:] pms = struct.unpack('%ss' % pms_len, data[:pms_len])[0] metadata['pre_master_secret'] = pms if self.keypair: try: cpms = self.keypair.private_decrypt(pms, RSA.sslv23_padding) except Exception as e: raise sslimCryptoError(str(e)) seed = self.c_rnd + self.s_rnd self.ms = self.__PRF(cpms, "master secret", seed, 48)[:48] metadata['master_secret'] = self.ms # Store the master secret in the sids dictionary self.store_ms(self.s_sid, self.ms) # From the master secret you generate the key material seed = self.s_rnd + self.c_rnd km = self.__key_material(self.cipher_suite['km_len'], self.s_rnd + self.c_rnd, self.ms) keys = self.__split_key_material(km) metadata['keys'] = keys self.cipher_suite['keys'] = keys if self.cipher_suite['cipher'] == 'stream': self.c_cryptobj = RC4.RC4(keys['client_enc_key']) self.s_cryptobj = RC4.RC4(keys['server_enc_key']) elif self.cipher_suite['cipher'] == 'block': self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['client_enc_key'], keys['client_iv'], 0, padding=0) self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['server_enc_key'], keys['server_iv'], 0, padding=0)
def set_skey(self, SKEY): if not self.block3b: self.block3b = self._gen_block3b(SKEY) crypta = RC4.RC4(sha('keyA' + self.S + SKEY).digest()) cryptb = RC4.RC4(sha('keyB' + self.S + SKEY).digest()) if self.initiator: self.encrypt = crypta.update self.decrypt = cryptb.update else: self.encrypt = cryptb.update self.decrypt = crypta.update self.encrypt('x' * 1024) # discard first 1024 bytes self.decrypt('x' * 1024)
def __init__(self): global allocated_sentinel, use_crypto, ccp_port, addr self.src_factory = Factory() self.src_factory.protocol = SrcProtocol self.src_factory.dst_p = self self.buf = '' self.sentinel_hex = allocated_sentinel self.session_key = self.sentinel_hex[const.SENTINEL_HEX_LEN:] self.rc4_handshake_c2d = RC4.RC4(self.session_key) self.rc4_handshake_d2c = RC4.RC4(self.session_key) self.rc4_tunnel = RC4.RC4(self.session_key) self.isFirst = True self.gotFillerDataCount = 0 self.send_chaff = LoopingCall(self.sendChaffReq) self.total_len = 0 self.start_time = time.clock() self.chaff_recv = 0 self.chaff_bytes = 0 self.cov_recv = 0 self.cov_bytes = 0 # Note that this is the host name if available, # otherwise the ip address # self.host_name = addr[0] self.state = const.STATE_0_UNI self.src_p = None self.handshake_ID = None self.tunnel_tag = None self.tunnel_type = const.HTTP_UNI_TUNNEL # We don't use the host or session_key parameters because the # only thing we use this encoder for is its digest method, which # does not depend on anything except the text. # self.encoder = HttpMoleCryptoEncoder('fakehost', 'fakekey') self.sent_count = 0
def dataReceived(self, data): if self.isFirst == True: self.mole = self.factory.ct_dp.getMole() self.session_key = self.mole.get_session_key() self.rc4 = RC4.RC4(self.session_key[const.SENTINEL_HEX_LEN:]) self.isFirst = False self.data_buf += data while len(self.data_buf) > 0: (status, self.data_buf) = self.tunnelIsReady(self.data_buf) if not status: break
def test_vectors(self): """ Test with test vectors from Wikipedia: http://en.wikipedia.org/wiki/Rc4 """ vectors = (('Key', 'Plaintext', 'BBF316E8D940AF0AD3'), ('Wiki', 'pedia', '1021BF0420'), ('Secret', 'Attack at dawn', '45A01F645FC35B383552544B9BF5')) rc4 = RC4.RC4() for key, plaintext, ciphertext in vectors: rc4.set_key(key) self.assertEqual(hexlify(rc4.update(plaintext)).upper(), ciphertext) self.assertEqual(rc4.final(), '')
def xor_encrypt(data, key): chunk_size = 16384 pos = 0 l = len(data) is_str = isinstance(data, str) res = '' while pos < l: rc4 = RC4.RC4(key) chunk = data[pos:pos + chunk_size] if is_str: res += rc4.update(chunk) else: data.update(rc4.update(chunk), pos) pos += chunk_size del rc4 return res
def M2Crypto_RC4(): global encryptionavg global decryptionavg from M2Crypto import RC4 startTime = time.time() rc4 = RC4.RC4() rc4.set_key(key) c = rc4.update(plainContent) totalTime = time.time() - startTime encryptionavg += totalTime #print totalTime print('RC4 Encryption: Total time: %.5f seconds' % totalTime) startTime = time.time() rc4.update(c) totalTime = time.time() - startTime decryptionavg += totalTime #print totalTime print('RC4 Decryption: Total time: %.5f seconds' % totalTime)
def __init__(self, host, session_key): if type(host) != str: raise TypeError('host must be a str (not %s)' % str(type(host))) if not host: raise ValueError('host must not be the empty string') self.host = host self.session_key = session_key self.offset = 0 self.seqno = 0 # TODO: check that the first 3000+ characters are thrown out. # The first part of an RC4 ciphertext are known to be weak. # self.rc4 = RC4.RC4(self.session_key) # Used to check that each instance is either used for encryption # or decryption, but never a mix # self.prev_crypto_op = None
o = opt[1] if o == '-': outf = sys.stdout else: outf = open(o, 'wb') if cmd < 0: raise argerr, "either -d or -e" if cmd > 1: raise argerr, "either -d or -e, not both" if cmd == 0: iv = inf.read(10) pp = getpass.getpass('Enter decryption passphrase: ') else: iv = Rand.rand_bytes(10) outf.write(iv) pp = getpass.getpass('Enter encryption passphrase: ') pp2 = getpass.getpass('Enter passphrase again: ') if pp != pp2: raise SystemExit, 'passphrase mismatch, I\'m outta here...' ci = RC4.RC4(pp + iv) del pp, iv while 1: buf = inf.read() if not buf: break outf.write(ci.update(buf)) outf.write(ci.final())
def arcfour_encrypt(key, data): c = RC4.RC4(key) return c.update(data)
def test_bad(self): if fips_mode: return rc4 = RC4.RC4(b'foo') self.assertNotEqual(hexlify(rc4.update(b'bar')).upper(), b'45678')
def reset_session_key(self): self.rc4 = RC4.RC4(self.session_key) self.seqno = 0
def test_bad(self): rc4 = RC4.RC4('foo') self.assertNotEqual(hexlify(rc4.update('bar')).upper(), '45678')
def __server_hello(self, data, metadata): # SERVER HELLO records have an inner version. version = struct.unpack('>H', data[:self.version_size])[0] metadata['handshake_version'] = version data = data[self.version_size:] (self.s_rnd, self.s_sid, sid_len) = self.__parse_rnd_and_sid(data) metadata['server_random'] = self.s_rnd metadata['server_sid'] = self.s_sid # Move past the random (32), sid_len (1) and SID (sid_len). data = data[32 + 1 + sid_len:] self.cipher_suite = struct.unpack('>H', data[:self.cipher_suite_size])[0] metadata['cipher_suite'] = self.cipher_suite data = data[self.cipher_suite_size:] if (self.cipher_suite not in self.decryptable_cipher_suites and self.keypair != None): raise sslimUnknownCipher("Can't decrypt cipher suite", self.cipher_suite) # Get details of the chosen cipher suite. Each cipher suite is # available as a method of the sslim_cipher_suites class. The method # names are all the 2 bytes for the cipher suite value preceeded by an # underscore (_0035, _002F, etc). # # See sslim_ciphers for details. cs = "_%04X" % self.cipher_suite if not hasattr(sslim_cipher_suites, cs): message = """Unknown cipher suite. This is likely just missing an entry in sslim_ciphers.py, please drop me a mail ([email protected]) with this message. Cipher suite""" raise sslimUnknownCipher(message, self.cipher_suite) method = getattr(sslim_cipher_suites, cs) cs = method() self.cipher_suite = cs.details metadata['cipher_suite_details'] = self.cipher_suite self.compression = struct.unpack('>B', data[:self.compression_size])[0] metadata['compression'] = self.compression data = data[self.compression_size:] if (self.compression not in self.compressions and self.keypair != None): raise sslimUnknownCompression("Unknown compression", self.compression) # The only compression allowed in the RFCs is deflate. If that # ever changes we need to pay attention to the value here. if (self.compression != self.NULL_COMPRESSION and self.keypair != None): self.c_zobj = zlib.decompressobj() self.s_zobj = zlib.decompressobj() if self.ver != self.SSLv3_0: # Go looking for extensions. extl = struct.unpack('>H', data[:self.extension_size])[0] self.__extensions( data[self.extension_size:self.extension_size + extl], 'server_extensions') # See if there is a client ticket extension. metadata['extensions'] = self.extensions['server_extensions'] data = data[self.extension_size:self.extension_size + extl] # Specifically for Session Tickets (RFC 5077). self.server_ticket = self.__find_extension( self.EXT_SESSIONTICKET_TYPE, 'server_extensions') # Only care about resuming if we have a keypair. if self.keypair != None: if ((self.s_sid != 0 and self.c_sid == self.s_sid) or self.client_ticket): # Session resuming. # First check the sid, then check the ticket. self.ms = self.check_sid(self.s_sid) if not self.ms: self.ms = self.check_sid(self.client_ticket) if not self.ms: raise sslimBadValue("Bad resume value") km = self.__key_material(self.cipher_suite['km_len'], self.s_rnd + self.c_rnd, self.ms) keys = self.__split_key_material(km) self.cipher_suite['keys'] = keys if self.cipher_suite['cipher'] == 'stream': self.c_cryptobj = RC4.RC4(keys['client_enc_key']) self.s_cryptobj = RC4.RC4(keys['server_enc_key']) elif self.cipher_suite['cipher'] == 'block': self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['client_enc_key'], keys['client_iv'], 0, padding=0) self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['server_enc_key'], keys['server_iv'], 0, padding=0) self.__callback('server_hello', metadata)
def encode(password): rc4 = RC4.RC4() rc4.set_key("#u82fyi8S5\017pPemw") return hexlify(rc4.update(password))
def __handshake(self, data): # The first byte is the hand-shake type. hst = struct.unpack('>B', data[:self.hs_type_size])[0] data = data[self.hs_type_size:] if hst not in self.HANDSHAKE_TYPES: raise sslimBadValue("Bad hst value", hst) # Client Hello (0x01) and Server Hello (0x02) have the 32 bytes # of random data in the same spot. if hst == self.CLIENT_HELLO: data = data[self.hs_hello_size:] (self.c_rnd, self.c_sid, sid_len) = self.__parse_rnd_and_sid(data) if self.ver != self.SSLv3_0: # Go looking for extensions. # Specifically for Session Tickets (RFC 5077). # Move past the random (32), sid_len (1) and SID (sid_len). data = data[32 + 1 + sid_len:] # We don't care what cipher suites or what compression method # the client supports. csl = struct.unpack('>H', data[:self.cipher_suite_size])[0] data = data[2 + csl:] cmpl = struct.unpack('>B', data[:self.compression_size])[0] data = data[1 + cmpl:] self.client_ticket = self.__find_extension( data, self.EXT_SESSIONTICKET_TYPE) elif hst == self.SERVER_HELLO: data = data[self.hs_hello_size:] (self.s_rnd, self.s_sid, sid_len) = self.__parse_rnd_and_sid(data) # Move past the random (32), sid_len (1) and SID (sid_len). data = data[32 + 1 + sid_len:] self.cipher_suite = struct.unpack('>H', data[:self.cipher_suite_size])[0] data = data[self.cipher_suite_size:] if self.cipher_suite not in self.cipher_suites: raise sslimUnknownCipher("Unknown cipher suite", self.cipher_suite) self.cipher_suite = self.cipher_suites[self.cipher_suite] self.compression = struct.unpack('>B', data[:self.compression_size])[0] data = data[self.compression_size:] if self.compression not in self.compressions: raise sslimUnknownCompression("Unknown compression", self.compression) # The only compression allowed in the RFCs is deflate. If that # ever changes we need to pay attention to the value here. if self.compression != self.NULL_COMPRESSION: self.c_zobj = zlib.decompressobj() self.s_zobj = zlib.decompressobj() if self.ver != self.SSLv3_0: # Go looking for extensions. # Specifically for Session Tickets (RFC 5077). self.server_ticket = self.__find_extension( data, self.EXT_SESSIONTICKET_TYPE) if (self.s_sid != 0 and self.c_sid == self.s_sid) or (self.client_ticket): # Session resuming. # First check the sid, then check the ticket. self.ms = self.check_sid(self.s_sid) if not self.ms: self.ms = self.check_sid(self.client_ticket) if not self.ms: raise sslimBadValue("Bad resume value") km = self.__key_material(self.cipher_suite['km_len'], self.s_rnd + self.c_rnd, self.ms) keys = self.__split_key_material(km) self.cipher_suite['keys'] = keys if self.cipher_suite['cipher'] == 'stream': self.c_cryptobj = RC4.RC4(keys['client_enc_key']) self.s_cryptobj = RC4.RC4(keys['server_enc_key']) elif self.cipher_suite['cipher'] == 'block': self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['client_enc_key'], keys['client_iv'], 0, padding=0) self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['server_enc_key'], keys['server_iv'], 0, padding=0) elif hst == self.EXT_SESSIONTICKET: # The first three bytes are the length, which we can skip # because we already have the entire handshake message. # We can also skip the next 4 bytes which are the lifetime hint. data = data[7:] # The next two bytes are the length of the session ticket. ticket_len = struct.unpack('>H', data[:2])[0] data = data[2:] if ticket_len != len(data): raise sslimBadValue("Bad ticket length", ticket_len) ticket = struct.unpack('%ss' % ticket_len, data[:ticket_len])[0] self.store_ms(ticket, self.ms) elif hst == self.CLIENT_KEY_EXCHANGE: if self.check_sid(self.s_sid): # XXX: The fact that the server session ID is in # the dictionary already is a really bad thing. # There should be no client key exchange message # if the client and server agree to resume. raise sslimBadValue("SID found with client key exchange") data = data[self.hs_key_exch_size:] # Client Hello (0x01) and Server Hello (0x02) have a version field # here while Client Key Exchange (0x10) puts the length here. We # are skipping the length. Older SSL implementations may not put # the length here (see section 7.4.7.1 of RFC5246) though. We # should check these two bytes and compare them with the modulus of # the private key. # XXX: The size of this is dependent upon the cipher suite chosen! # Section 7.4.7.1 of RFC5246 details what these bytes mean for # RSA authentication! if self.ver == self.SSLv3_0: if self.cipher_suite['key_exch'] != 'RSA': raise sslimUnknownCipher("SSLv3 not RSA key exchange") pms = data else: # The first two bytes are the length of the key. pms_len = int( struct.unpack('>H', data[:self.hs_pms_len_size])[0]) data = data[self.hs_pms_len_size:] pms = struct.unpack('%ss' % pms_len, data[:pms_len])[0] try: cpms = self.keypair.private_decrypt(pms, RSA.sslv23_padding) except: raise sslimCryptoError() seed = self.c_rnd + self.s_rnd self.ms = self.__PRF(cpms, "master secret", seed, 48)[:48] # Store the master secret in the sids dictionary self.store_ms(self.s_sid, self.ms) # From the master secret you generate the key material seed = self.s_rnd + self.c_rnd km = self.__key_material(self.cipher_suite['km_len'], self.s_rnd + self.c_rnd, self.ms) keys = self.__split_key_material(km) self.cipher_suite['keys'] = keys if self.cipher_suite['cipher'] == 'stream': self.c_cryptobj = RC4.RC4(keys['client_enc_key']) self.s_cryptobj = RC4.RC4(keys['server_enc_key']) elif self.cipher_suite['cipher'] == 'block': self.c_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['client_enc_key'], keys['client_iv'], 0, padding=0) self.s_cryptobj = EVP.Cipher(self.cipher_suite['algo'], keys['server_enc_key'], keys['server_iv'], 0, padding=0)