Source code for covertutils.crypto.keys.standardcyclingkey

import codecs

from covertutils.crypto.keys import CyclingKey, EncryptionKey

from covertutils.helpers import sxor

from covertutils.crypto.algorithms import StandardCyclingAlgorithm


[docs]class StandardCyclingKey( CyclingKey, EncryptionKey ) : # random bytes for global salting. Never transmitted. __salt = codecs.decode( 'b2fb06410b0623bae23b5db0c43414c0ce08ae24b40808f0a25f5ca39c69bc1c' '1bbc9a53a91a596d2b80991aaeb644b27f46a1338024fff3f27b8db412a38691' 'e51b80349991d50bef8baa14c5ee0b446ddbe1af122bed442d282be0c4faf1f0' '423269aa5fbee1349672f4f30b1362ef18e5f1b68bdba3e6062e072bea79f5f1' 'e0848b04a5be51ebe852177ab96e4f054c40f18c3b8ec3bbae4a847a3860c3cf' '630e0bb327aa9dc8609e0bc9b6dbee6bd3597108f62caecf9df60acdbf8134bd' '7cc4457979bb54f8c7cfeb076dc843222b24cb0727b423a434f52f37a7da106a' '6e576e05c48223a99aafce6e9fbd24b641217662b91d060524deae84de5588c9', 'hex')
[docs] def __init__ ( self, passphrase, cycling_algorithm = None, cycle = True, salt = None, **kw ) : """ :param str passphrase: The key will be created against a `passphrase`. Passphrase will be the primary seed of all cycling. If a Secure __hash function is used, it is length won't provide additional security, or better encryption. :param object cycling_algorithm: The cycling algorithm determines the key quality. By default the :class:CyclingAlgorithm class is used, but `hashlib.md5`, `hashlib.sha256` and every hash function object with a `digest()` method can be used. :param str salt: Salt further differentiates the key from other keys with the same `passphrase`. For two keys to be compatible they must have the same `salt` too. If not specified a default salt is used. """ super( StandardCyclingKey, self ).__init__( passphrase, **kw ) self.__counter = 0 self.cycle_enabled = cycle self.cycling_algorithm = cycling_algorithm if self.cycling_algorithm == None: self.cycling_algorithm = StandardCyclingAlgorithm if salt != None : self.__salt = salt self.initial_key = self.__createKey( passphrase ) self.reset() del(passphrase) # just to be sure
def __createKey( self, seed ) : return self.__hash( seed ) def __hash( self, message ) : try : return self.cycling_algorithm ( bytearray(message, 'utf8') + self.__salt ).digest() except : return self.cycling_algorithm ( message + self.__salt ).digest()
[docs] def cycle( self, rounds = 1 ) : if self.cycle_enabled == False : return for i in range( rounds ) : self.__previous_key = self.current_key self.current_key = self.__hash( self.current_key ) self.__counter += 1 return self.current_key
[docs] def setCycle( self, cycle ) : assert cycle >= 1 d = self.__counter - cycle if d < 0 : self.cycle( -d ) elif d > 0 : self.reset() self.cycle( cycle )
[docs] def reset( self ) : self.current_key = self.initial_key self.cycle( 1 ) self.__previous_key = self.initial_key self.__counter = 0
[docs] def getKeyBytes( self, length = None ) : return self.__getKeyBytesFromKey( self.current_key, length )
[docs] def getUUIDBytes( self, length = None ) : return self.__getKeyBytesFromKey( self.initial_key, length)
[docs] def getKeyLength( self ) : return len(self.current_key)
def __getKeyBytesFromKey( self, key, length = None ) : if None : numOfBytes = len(self.key) return key[:length]
[docs] def xor( self, message, cycle = True ) : # message = bytearray( message ) key = self.current_key final_key = key while len(message) > len(final_key) : if cycle : self.cycle() final_key += self.getKeyBytes()[:2*self.getKeyLength()//3] # 2/3 of the current key length will be used as key try : s1 = bytearray(message) s2 = bytearray(final_key) except TypeError: s1 = bytearray(message, 'utf8') s2 = final_key if cycle : self.cycle() # print (s1, s2) ret = bytearray([a ^ b for a,b in zip(s1,s2)]) # LOG.debug("XORING:\n%s\n%s\n-> %s" % (s1.encode('hex'), s2.encode('hex'), ret.encode('hex'))) try : return str(ret, encoding='UTF-8') except : return str(ret)
[docs] def getCycles( self ) : """ :rtype: int :return: Returns the number of rounds the key has cycled. """ return self.__counter
[docs] def encrypt( self, plain ) : return self.xor( plain )
[docs] def decrypt( self, crypt ) : return self.xor( crypt )