def _compute_mac(self): """Compute MAC without any FSM checks.""" if self._tag: return self._tag else: if self.mode == MODE_CCM: if self._assoc_len is None: self._start_ccm(assoc_len=self._cipherMAC.get_len()) if self._msg_len is None: self._start_ccm(msg_len=0) self._cipherMAC.zero_pad() self._tag = strxor(self._cipherMAC.digest(), self._s_0)[:self._mac_len] if self.mode == MODE_GCM: self._cipherMAC.zero_pad() auth_len = self._cipherMAC.get_len() - self._msg_len for tlen in (auth_len, self._msg_len): self._cipherMAC.update(long_to_bytes(8 * tlen, 8)) s_tag = self._cipherMAC.digest() self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len] if self.mode == MODE_EAX: tag = bchr(0) * self.block_size for i in xrange(3): tag = strxor(tag, self._omac[i].digest()) self._tag = tag[:self._mac_len] if self.mode == MODE_SIV: self._tag = self._cipherMAC.derive() return self._tag
def encode(self,k,M,L=""): """ Encode a message using OAEP. @type M: byte string @param M: to encode using Optimal Asymmetric Encryption Padding @type k: int @param k: Size of the private key modulus in bytes @type L: string @param L: label for the encoding """ # Calculate label hash, unless it is too long if L: limit = getattr(self.__hash,"input_limit",None) if limit and len(L) > limit: raise ValueError("label too long") lHash = self.__hash(L).digest() # Check length of message against size of key modulus mLen = len(M) hLen = len(lHash) if mLen > k - 2*hLen - 2: raise ValueError("message too long") # Perform the encoding PS = "\x00" * (k - mLen - 2*hLen - 2) DB = lHash + PS + "\x01" + M assert len(DB) == k - hLen - 1, "DB length is incorrect" seed = self.__randbytes(hLen) dbMask = self.__generateMgf1(seed,k - hLen - 1) maskedDB = strxor(DB,dbMask) seedMask = self.__generateMgf1(maskedDB,hLen) maskedSeed = strxor(seed,seedMask) return "\x00" + maskedSeed + maskedDB
def digest(self): try: mac = cbc_mac(self.key, ''.join(self.macs)) # Zero IV except TypeError: raise ValueError('Not all chunk MACs have been submitted') return strxor(mac[:4], mac[4:8]) + strxor(mac[8:12], mac[12:])
def digest(self): """Return the **binary** (non-printable) MAC tag of the message that has been authenticated so far. :return: The MAC tag, computed over the data processed so far. Binary form. :rtype: byte string """ if self._mac_tag is not None: return self._mac_tag if self._data_size > self._max_size: raise ValueError("MAC is unsafe for this message") if len(self._cache) == 0 and self._before_last_ct is not None: # Last block was full pt = strxor(strxor(self._before_last_ct, self._k1), self._last_pt) else: # Last block is partial (or message length is zero) ext = self._cache + bchr(0x80) +\ bchr(0) * (self.digest_size - len(self._cache) - 1) pt = strxor(strxor(self._last_ct, self._k2), ext) cipher = self._factory.new(self._key, self._factory.MODE_ECB, **self._cipher_params) self._mac_tag = cipher.encrypt(pt) return self._mac_tag
def digest(self): """Return the **binary** (non-printable) MAC of the message that has been authenticated so far. This method does not change the state of the MAC object. You can continue updating the object after calling this function. :Return: A byte string of `digest_size` bytes. It may contain non-ASCII characters, including null bytes. """ if self._mac_tag is not None: return self._mac_tag if self._data_size > self._max_size: raise ValueError("MAC is unsafe for this message") if len(self._cache) == 0 and self._before_last_ct is not None: ## Last block was full pt = strxor(strxor(self._before_last_ct, self._k1), self._last_pt) else: ## Last block is partial (or message length is zero) ext = self._cache + bchr(0x80) +\ bchr(0) * (self.digest_size - len(self._cache) - 1) pt = strxor(strxor(self._last_ct, self._k2), ext) cipher = self._factory.new(self._key, self._factory.MODE_ECB, **self._cipher_params) self._mac_tag = cipher.encrypt(pt) return self._mac_tag
def digest(self): """Return the **binary** (non-printable) MAC tag of the message that has been authenticated so far. :return: The MAC tag, computed over the data processed so far. Binary form. :rtype: byte string """ bs = self._block_size if self._mac_tag is not None and not self._update_after_digest: return self._mac_tag if self._data_size > self._max_size: raise ValueError("MAC is unsafe for this message") if self._cache_n == 0 and self._data_size > 0: # Last block was full pt = strxor(self._last_pt, self._k1) else: # Last block is partial (or message length is zero) partial = self._cache[:] partial[self._cache_n:] = b'\x80' + b'\x00' * (bs - self._cache_n - 1) pt = strxor(strxor(self._last_ct, partial), self._k2) self._mac_tag = self._ecb.encrypt(pt)[:self.digest_size] return self._mac_tag
def EME_D(T,K,C): # create a AES block cipher with key L # default AES mode is ECB # default n = 128 bits, 16 bytes, P = m * 128 length n = 16 m = len(C)/16 # how many blocks do we have # create a AES block cipher, use ECB mode cipher = AES.new(K,AES.MODE_ECB) IV = '' for i in range(0,n): IV = IV + '0' # TO DO : L needs to time 2 later ! L = cipher.encrypt(IV) L = shift_left(L, 1) count = 0 CCC_list = [] # store all the PPP obtained for i in range(1,m+1): C_i = C[count * n :i*n] count = count + 1 # TO DO version : PP = strxor_c(P_i, pow(2,i-1) * L) CC = strxor.strxor(C_i, shift_left(L, i-1)) CCC = cipher.decrypt(CC) CCC_list.append(CCC) SC = " " * 16 for i in range(1,len(CCC_list)): SC = strxor.strxor(SC,CCC_list[i]) MC = strxor.strxor(CCC_list[0],SC) MC = strxor.strxor(MC,T) MP = cipher.decrypt(MC) M = strxor.strxor(MP,MC) PPP_list = [" "] * m # store all the PPP obtained for i in range(1,len(CCC_list)): PPP = strxor.strxor(CCC_list[i],shift_left(M,i)) PPP_list[i] = PPP SP = " " * n for i in range(1,len(PPP_list)): SP = strxor.strxor(PPP_list[i],SP) PPP_list[0] = strxor.strxor(MP,SP) PPP_list[0] = strxor.strxor(PPP_list[0],T) P_list = [] for i in range (0,len(PPP_list)): PP = cipher.decrypt(PPP_list[i]) P = strxor.strxor(PP,shift_left(L,i)) P_list.append(P) plaintext = "" for i in range(0,len(P_list)): plaintext = plaintext + P_list[i] return plaintext
def encode(self,k,M,L=""): """Encode a message using OAEP. This method encodes a byte string 'M' using Optimal Asymmetric Encryption Padding. The argument 'k' must be the size of the private key modulus in bytes. If specified, 'L' is a label for the encoding. """ # Calculate label hash, unless it is too long if L: limit = getattr(self.hash,"input_limit",None) if limit and len(L) > limit: raise ValueError("label too long") lHash = self.hash(L).digest() # Check length of message against size of key modulus mLen = len(M) hLen = len(lHash) if mLen > k - 2*hLen - 2: raise ValueError("message too long") # Perform the encoding PS = "\x00" * (k - mLen - 2*hLen - 2) DB = lHash + PS + "\x01" + M assert len(DB) == k - hLen - 1, "DB length is incorrect" seed = self.randbytes(hLen) dbMask = self.mgf(seed,k - hLen - 1) maskedDB = strxor(DB,dbMask) seedMask = self.mgf(maskedDB,hLen) maskedSeed = strxor(seed,seedMask) return "\x00" + maskedSeed + maskedDB
def _digest(self, last_data): if len(last_data) == self._bs: last_block = strxor(last_data, self._k1) else: last_block = strxor(last_data + bchr(128) + bchr(0) * (self._bs - 1 - len(last_data)), self._k2) tag = self._mac.encrypt(last_block) return tag
def attacker_send_forged_message(sender, recipient, amount): # Assume attacker can create this account. fake_sender = (b'M' * min(len(sender), 11)) + sender[11:] # Assume this message fails or otherwise has no effect. frontend_send_message(fake_sender, recipient, amount) m = attacker_peek_last_sent_message() message, iv, mac = m[:-32], m[-32:-16], m[-16:] forged_message = b'from=' + sender + message[len(sender)+5:] forged_iv = strxor(iv, strxor(message[:16], forged_message[:16])) attacker_inject_message(forged_message + forged_iv + mac)
def encrypt(self, message): """Produce the PKCS#1 OAEP encryption of a message. This function is named ``RSAES-OAEP-ENCRYPT``, and is specified in section 7.1.1 of RFC3447. :Parameters: message : string The message to encrypt, also known as plaintext. It can be of variable length, but not longer than the RSA modulus (in bytes) minus 2, minus twice the hash output size. :Return: A string, the ciphertext in which the message is encrypted. It is as long as the RSA modulus (in bytes). :Raise ValueError: If the RSA key length is not sufficiently long to deal with the given message. """ # TODO: Verify the key is RSA randFunc = self._key._randfunc # See 7.1.1 in RFC3447 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes hLen = self._hashObj.digest_size mLen = len(message) # Step 1b ps_len = k-mLen-2*hLen-2 if ps_len<0: raise ValueError("Plaintext is too long.") # Step 2a lHash = self._hashObj.new(self._label).digest() # Step 2b ps = bchr(0x00)*ps_len # Step 2c db = lHash + ps + bchr(0x01) + message # Step 2d ros = randFunc(hLen) # Step 2e dbMask = self._mgf(ros, k-hLen-1) # Step 2f maskedDB = strxor(db, dbMask) # Step 2g seedMask = self._mgf(maskedDB, hLen) # Step 2h maskedSeed = strxor(ros, seedMask) # Step 2i em = bchr(0x00) + maskedSeed + maskedDB # Step 3a (OS2IP), step 3b (RSAEP), part of step 3c (I2OSP) m = self._key.encrypt(em, 0)[0] # Complete step 3c (I2OSP) c = bchr(0x00)*(k-len(m)) + m return c
def __init__(self, key, msg=b(""), digestmod=None): """Create a new HMAC object. :Parameters: key : byte string secret key for the MAC object. It must be long enough to match the expected security level of the MAC. However, there is no benefit in using keys longer than the `digest_size` of the underlying hash algorithm. msg : byte string The very first chunk of the message to authenticate. It is equivalent to an early call to `update()`. Optional. :Parameter digestmod: The hash algorithm the HMAC is based on. Default is `Crypto.Hash.MD5`. :Type digestmod: A hash module or object instantiated from `Crypto.Hash` """ if digestmod is None: digestmod = MD5 if msg is None: msg = b("") #: Size of the MAC tag self.digest_size = digestmod.digest_size self._digestmod = digestmod try: if len(key) <= digestmod.block_size: # Step 1 or 2 key_0 = key + bchr(0) * (digestmod.block_size - len(key)) else: # Step 3 hash_k = digestmod.new(key).digest() key_0 = hash_k + bchr(0) * (digestmod.block_size - len(hash_k)) except AttributeError: # Not all hash types have "block_size" raise ValueError("Hash type incompatible to HMAC") # Step 4 key_0_ipad = strxor(key_0, bchr(0x36) * len(key_0)) # Start step 5 and 6 self._inner = digestmod.new(key_0_ipad) self._inner.update(msg) # Step 7 key_0_opad = strxor(key_0, bchr(0x5c) * len(key_0)) # Start step 8 and 9 self._outer = digestmod.new(key_0_opad)
def encrypt(self, message): """Encrypt a message with PKCS#1 OAEP. :param message: The message to encrypt, also known as plaintext. It can be of variable length, but not longer than the RSA modulus (in bytes) minus 2, minus twice the hash output size. For instance, if you use RSA 2048 and SHA-256, the longest message you can encrypt is 190 byte long. :type message: bytes/bytearray/memoryview :returns: The ciphertext, as large as the RSA modulus. :rtype: bytes :raises ValueError: if the message is too long. """ # See 7.1.1 in RFC3447 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes hLen = self._hashObj.digest_size mLen = len(message) # Step 1b ps_len = k - mLen - 2 * hLen - 2 if ps_len < 0: raise ValueError("Plaintext is too long.") # Step 2a lHash = self._hashObj.new(self._label).digest() # Step 2b ps = b'\x00' * ps_len # Step 2c db = lHash + ps + b'\x01' + _copy_bytes(None, None, message) # Step 2d ros = self._randfunc(hLen) # Step 2e dbMask = self._mgf(ros, k-hLen-1) # Step 2f maskedDB = strxor(db, dbMask) # Step 2g seedMask = self._mgf(maskedDB, hLen) # Step 2h maskedSeed = strxor(ros, seedMask) # Step 2i em = b'\x00' + maskedSeed + maskedDB # Step 3a (OS2IP) em_int = bytes_to_long(em) # Step 3b (RSAEP) m_int = self._key._encrypt(em_int) # Step 3c (I2OSP) c = long_to_bytes(m_int, k) return c
def derive(self): """"Derive a secret from the vector of components. :Return: a byte string, as long as the block length of the cipher. """ if len(self._last_string) >= 16: final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache) else: padded = (self._last_string + bchr(128) + bchr(0) * 15)[:16] final = strxor(padded, self._double(self._cache)) mac = CMAC.new(self._key, msg=final, ciphermod=self._ciphermod) return mac.digest()
def ansi_x9_17(V, key): ''' Generator for ansi_x9_17 PRNG V: seed. It should be a string of length 8 key: concat of keys K1 & K2. It should be a string of length 16''' des3 = DES3.new(key, DES3.MODE_ECB) while True: EDT = des3.encrypt(hex(int(time()*10**6))[-8:]) R = des3.encrypt(strxor(V, EDT)) V = des3.encrypt(strxor(R, EDT)) yield long(struct.unpack('L', R)[0])
def jamburound_inv(c, obj, Y='\x00'*8, X='\x00'*8): X, Y = split(obj.encrypt(X+Y), 8) R = X for block in blocks(c, 8): C = block print strhex(C), " -> ", X, Y = split(obj.encrypt(X+Y), 8) Y = strxor(Y, R) C = strxor(C, Y) X = strxor(X, C) R = strxor(R, X) print strhex(C) yield C
def decrypt_ctr(key, ciphertext): """decrypt ciphertext with cbc mode""" message = '' iv = ciphertext[0:16] for i in range(16, len(ciphertext), 16): inputblock = ciphertext[i:i+16] cipher = AES.new(key, AES.MODE_ECB) xorkey = cipher.encrypt(long_to_bytes(bytes_to_long(iv)+(i/16-1))) if len(inputblock) == 16: message += strxor(inputblock, xorkey) else: message += strxor(inputblock, xorkey[:len(inputblock)]) return message
def jamburound(m, obj, Y='\x00'*8, X='\x00'*8): X, Y = split(obj.encrypt(X+Y), 8) R = X for block in blocks(m, 8): P = block print strhex(P), " -> ", X, Y = split(obj.encrypt(X+Y), 8) X = strxor(X, P) Y = strxor(Y, R) R = strxor(R, X) P = strxor(P, Y) print strhex(P) yield P
def aes_key_unwrap(K, C): """ aes key unwrap : :rfc:`3394` 2.2.2 :param str K: key encrytpion key :param str C: ciphertext """ assert len(K) * 8 in [128, 192, 256] # key bits assert len(C) % 8 == 0 # 64 bit blok n = len(C) / 8 - 1 # 64bit blocks R = slice(C, 8) A = R[0] # Set A = C[0] (=R[0]) R[0] = [b'\0\0\0\0\0\0\0\0'] # init R[0] # For i = 1 to n ; R[i] = C[i] _AES = AES.AESCipher(K) for j in range(5, -1, -1): # For j = 5 to 0 for i in range(n, 0, -1): # For i = n to 1 t = pack("!q", (n * j) + i) # t = n * j + i src = strxor(A, t) + R[i] # A ^ t B = _AES.decrypt(src) # B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i A = B[:8] # A = MSB(64, B) R[i] = B[8:] # R[i] = LSB(64, B) if A == AES_IV: return "".join(R[1:]) # For i = 1 to n; P[i] = R[i] else: raise Exception("unwrap failed: Invalid IV")
def aes_key_wrap(K, P): """ aes key wrap : :rfc:`3394` 2.2.1 :param str K: key encrytpion key :param str P: plaintext """ assert len(K) * 8 in [128, 192, 256] # key bits assert len(P) % 8 == 0 # 64 bit blok n = len(P) / 8 # 64 bit blocks A = AES_IV # Set A = IV R = [b'\0\0\0\0\0\0\0\0'] + slice(P, 8) # copy of slice every 8 octets # For i = 1 to n ; R[i] = P[i] _AES = AES.AESCipher(K) for j in range(0, 6): # For j=0 to 5 for i in range(1, n + 1): # For i=1 to n B = _AES.encrypt(A + R[i]) # B = AES(K, A | R[i]) R[i] = B[8:] # R[i] = LSB(64, B) t = pack("!q", (n * j) + i) A = strxor(B[:8], t) # A = MSB(64, B) ^ t where t = (n*j)+i R[0] = A # Set C[0] = A return "".join(R) # For i = 1 to n C[i] = R[i]
def test_bytearray(self): term1 = unhexlify(b"ff339a83e5cd4cdf5649") term1_ba = bytearray(term1) term2 = unhexlify(b"383d4ba020573314395b") result = unhexlify(b"c70ed123c59a7fcb6f12") self.assertEqual(strxor(term1_ba, term2), result)
def _digest(self): if self._mac_tag: return self._mac_tag if self._assoc_len is None: assert(isinstance(self._cache, list)) self._assoc_len = sum([len(x) for x in self._cache]) if self._msg_len is not None: self._start_mac() else: if self._cumul_assoc_len < self._assoc_len: raise ValueError("Associated data is too short") if self._msg_len is None: self._msg_len = 0 self._start_mac() if self._cumul_msg_len != self._msg_len: raise ValueError("Message is too short") # Both associated data and payload are concatenated with the least # number of zero bytes (possibly none) that align it to the # 16 byte boundary (A.2.2 and A.2.3) self._pad_cache_and_update() # Step 8 in 6.1 (T xor MSB_Tlen(S_0)) self._mac_tag = strxor(self._t, self._s_0)[:self._mac_len] return self._mac_tag
def update(self,data): assert(len(data) == self._seedlen_bytes) #self.v = self.inc_byte_string_array(self.v) #temp=self.aes.encrypt(self.v) self.v.incr() temp=self.aes.encrypt(self.v.get_string()) #print "Key: \t\t", binascii.b2a_hex(self.key), "\nVector: \t", binascii.b2a_hex(self.v), "\nAES: \t\t", binascii.b2a_hex(temp) print "\nAES: \t\t", binascii.b2a_hex(temp) #self.v = self.inc_byte_string_array(self.v) #temp+=self.aes.encrypt(self.v) self.v.incr() temp+=self.aes.encrypt(self.v.get_string()) print "\nAES: \t\t", binascii.b2a_hex(self.aes.encrypt(self.v.get_string())) #print "Key: \t\t", binascii.b2a_hex(self.key), "\nVector: \t", binascii.b2a_hex(self.v), "\nAES: \t\t", binascii.b2a_hex(self.aes.encrypt(self.v)) assert(len(temp) == self._seedlen_bytes) temp=strxor.strxor(temp,data) #(self.key,self.v) = (temp[0:self._keylen_bytes], temp[self._keylen_bytes:len(temp)]) (self.key,self.v) = (temp[0:self._keylen_bytes], byte_counter(temp[self._keylen_bytes:len(temp)])) assert(len(self.key) == self._keylen_bytes) assert(len(self.v) == self._keylen_bytes) self.aes = AES.new(self.key,AES.MODE_ECB) return
def digest(self): """Compute the *binary* MAC tag. The caller invokes this function at the very end. This method returns the MAC that shall be sent to the receiver, together with the ciphertext. :Return: the MAC, as a byte string. """ if self.digest not in self._next: raise TypeError("digest() cannot be called when decrypting" " or validating a message") self._next = [self.digest] if self._mac_tag: return self._mac_tag if self._assoc_len is None: self._start_ccm(assoc_len=self._signer.data_signed_so_far()) if self._msg_len is None: self._start_ccm(msg_len=0) # Both associated data and payload are concatenated with the least # number of zero bytes (possibly none) that align it to the # 16 byte boundary (A.2.2 and A.2.3) self._signer.zero_pad() # Step 8 in 6.1 (T xor MSB_Tlen(S_0)) self._mac_tag = strxor(self._signer.digest(), self._s_0)[:self._mac_len] return self._mac_tag
def test_memoryview(self): term1 = unhexlify(b"ff339a83e5cd4cdf5649") term1_mv = memoryview(term1) term2 = unhexlify(b"383d4ba020573314395b") result = unhexlify(b"c70ed123c59a7fcb6f12") self.assertEqual(strxor(term1_mv, term2), result)
def update(self, item): """Pass the next component of the vector. The maximum number of components you can pass is equal to the block length of the cipher (in bits) minus 1. :Parameters: item : byte string The next component of the vector. :Raise TypeError: when the limit on the number of components has been reached. :Raise ValueError: when the component is empty """ if not item: raise ValueError("A component cannot be empty") if self._n_updates==0: raise TypeError("Too many components passed to S2V") self._n_updates -= 1 mac = CMAC.new(self._key, msg=self._last_string, ciphermod=self._ciphermod, cipher_params=self._cipher_params) self._cache = strxor(self._double(self._cache), mac.digest()) self._last_string = item
def verify(self, received_mac_tag): """Validate the *binary* MAC tag. The caller invokes this function at the very end. This method checks if the decrypted message is indeed valid (that is, if the key is correct) and it has not been tampered with while in transit. :Parameters: received_mac_tag : byte string This is the *binary* MAC, as received from the sender. :Raises MacMismatchError: if the MAC does not match. The message has been tampered with or the key is incorrect. """ if self.verify not in self._next: raise TypeError("verify() cannot be called" " when encrypting a message") self._next = [self.verify] if not self._mac_tag: tag = bchr(0) * self.block_size for i in range(3): tag = strxor(tag, self._omac[i].digest()) self._mac_tag = tag[:self._mac_len] secret = get_random_bytes(16) mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag) mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag) if mac1.digest() != mac2.digest(): raise ValueError("MAC check failed")
def pack_key(self): """Packs the key into the MEGA format. The format is as follows: <128bit key XOR iv + mac><64bit iv><64bit mac>.""" key = strxor(self.key, self.iv + self.mac) return key + self.iv + self.mac
def _ige(message, key, iv, operation="decrypt"): """Given a key, given an iv, and message do whatever operation asked in the operation field. Operation will be checked for: "decrypt" and "encrypt" strings. Returns the message encrypted/decrypted. message must be a multiple by 16 bytes (for division in 16 byte blocks) key must be 32 byte iv must be 32 byte (it's not internally used in AES 256 ECB, but it's needed for IGE)""" message = bytes(message) if len(key) != 32: raise ValueError("key must be 32 bytes long (was " + str(len(key)) + " bytes)") if len(iv) != 32: raise ValueError("iv must be 32 bytes long (was " + str(len(iv)) + " bytes)") cipher = AES.new(key, AES.MODE_ECB, iv) blocksize = cipher.block_size if len(message) % blocksize != 0: raise ValueError("message must be a multiple of 16 bytes (try adding " + str(16 - len(message) % 16) + " bytes of padding)") ivp = iv[0:blocksize] ivp2 = iv[blocksize:] ciphered = bytes() for i in range(0, len(message), blocksize): indata = message[i:i+blocksize] if operation == "decrypt": xored = strxor(indata, ivp2) decrypt_xored = cipher.decrypt(xored) outdata = strxor(decrypt_xored, ivp) ivp = indata ivp2 = outdata elif operation == "encrypt": xored = strxor(indata, ivp) encrypt_xored = cipher.encrypt(xored) outdata = strxor(encrypt_xored, ivp2) ivp = outdata ivp2 = indata else: raise ValueError("operation must be either 'decrypt' or 'encrypt'") ciphered += outdata return ciphered
def __init__(self, factory, nonce, mac_len, cipher_params): if factory.block_size != 16: raise ValueError("OCB mode is only available for ciphers" " that operate on 128 bits blocks") self.block_size = 16 """The block size of the underlying cipher, in bytes.""" self.nonce = nonce """Nonce used for this session.""" if len(nonce) not in range(1, 16): raise ValueError("Nonce must be at most 15 bytes long") self._mac_len = mac_len if not 8 <= mac_len <= 16: raise ValueError("MAC tag must be between 8 and 16 bytes long") # Cache for MAC tag self._mac_tag = None # Cache for unaligned associated data self._cache_A = b("") # Cache for unaligned ciphertext/plaintext self._cache_P = b("") # Allowed transitions after initialization self._next = [self.update, self.encrypt, self.decrypt, self.digest, self.verify] # Compute Offset_0 params_without_key = dict(cipher_params) key = params_without_key.pop("key") nonce = bchr(self._mac_len << 4 & 0xFF) + bchr(0) * (14 - len(self.nonce)) + bchr(1) + self.nonce bottom = bord(nonce[15]) & 0x3F # 6 bits, 0..63 ktop = factory.new(key, factory.MODE_ECB, **params_without_key).encrypt( nonce[:15] + bchr(bord(nonce[15]) & 0xC0) ) stretch = ktop + strxor(ktop[:8], ktop[1:9]) # 192 bits offset_0 = long_to_bytes(bytes_to_long(stretch) >> (64 - bottom), 24)[8:] # Create low-level cipher instance raw_cipher = factory._create_base_cipher(cipher_params) if cipher_params: raise TypeError("Unknown keywords: " + str(cipher_params)) self._state = VoidPointer() result = _raw_ocb_lib.OCB_start_operation( raw_cipher.get(), offset_0, c_size_t(len(offset_0)), self._state.address_of() ) if result: raise ValueError("Error %d while instantiating the OCB mode" % result) # Ensure that object disposal of this Python object will (eventually) # free the memory allocated by the raw library for the cipher mode self._state = SmartPointer(self._state.get(), _raw_ocb_lib.OCB_stop_operation) # Memory allocated for the underlying block cipher is now owed # by the cipher mode raw_cipher.release()
def update(self, item): """Pass the next component of the vector. The maximum number of components you can pass is equal to the block length of the cipher (in bits) minus 1. :Parameters: item : byte string The next component of the vector. :Raise TypeError: when the limit on the number of components has been reached. """ if self._n_updates == 0: raise TypeError("Too many components passed to S2V") self._n_updates -= 1 mac = CMAC.new(self._key, msg=self._last_string, ciphermod=self._ciphermod, cipher_params=self._cipher_params) self._cache = strxor(self._double(self._cache), mac.digest()) self._last_string = _copy_bytes(None, None, item)
def get_decrypted_msg(self, msg, sha_key_string, sha_integrity_key_string): """ Checks integrity and decrypts message - msg: 64 byte payload ( 32 byte message + 32 byte integrity) - sha_key_string : key in bytes Returns: - bytes : Decrypted message in bytes """ integrity = msg[32:] msg = msg[:32] decrypted_msg = strxor(SHA256.new(sha_key_string).digest(), msg) sha_integrity = SHA256.new(decrypted_msg + sha_integrity_key_string).digest() if not sha_integrity == integrity: print("Message is tampered") raise ValueError('message is tampered') return decrypted_msg
def less_leaky_encipher(key, A): # I use the variables A, X, Y, and Z here just as in the previous routine # Let's compute Yvec just as we did before. assert (len(A) == 16) permutation = AES.new(key, AES.MODE_ECB) Z = permutation.encrypt(A) lastroundkey = aes128_lastroundkey(key) #print("key",lastroundkey) Y = strxor(Z, lastroundkey) Yvec = [ord(i) for i in Y] # Now we invert the SubBytes operation, but only store the set of the upper 4 bits of the result #Xvec = map(Sinv, Yvec) # This is the *list* of full bytes at the start of the 10th round Xvec = [Sinv[y] for y in Yvec] X = frozenset( map(lambda x: x >> 4, Xvec) ) # And now we form the *set* of values with the lower 4 bits truncated # Return the enciphering of A together with the *set* of cache lines accessed in round 10 return [Z, X]
def encrypt_cbc(filename): img = Image.open(filename) p = np.array(img) p_arrstr = np.char.mod('%.0f', p) old_encrypted = b'' for r_ind, row in enumerate(p_arrstr): for ind, group in enumerate(grouper(row, block_size, '0')): row_str = bytearray(''.join(group).encode('utf-8')) try: xor_len = min(len(row_str), len(old_encrypted)) row_str = strxor.strxor(row_str[:xor_len], old_encrypted[:xor_len]) except: pass encrypted = encrypt(row_str, b'AaBbNnnJfKklre20') for i in range(block_size): try: p[r_ind][ind * block_size + i] = encrypted[i] except IndexError: pass old_encrypted = encrypted[:block_size] im = Image.fromarray(p) im.save("cbc_crypto.bmp")
def PBKDF2(password, salt, dkLen=16, count=1000, prf=None): """Derive one or more keys from a password (or passphrase). This performs key derivation according to the PKCS#5 standard (v2.0), by means of the ``PBKDF2`` algorithm. :Parameters: password : string The secret password or pass phrase to generate the key from. salt : string A string to use for better protection from dictionary attacks. This value does not need to be kept secret, but it should be randomly chosen for each derivation. It is recommended to be at least 8 bytes long. dkLen : integer The cumulative length of the desired keys. Default is 16 bytes, suitable for instance for `Crypto.Cipher.AES`. count : integer The number of iterations to carry out. It's recommended to use at least 1000. prf : callable A pseudorandom function. It must be a function that returns a pseudorandom string from two parameters: a secret and a salt. If not specified, HMAC-SHA1 is used. :Return: A byte string of length `dkLen` that can be used as key material. If you wanted multiple keys, just break up this string into segments of the desired length. """ password = tobytes(password) if prf is None: prf = lambda p, s: HMAC.new(p, s, SHA1).digest() key = b('') i = 1 while len(key) < dkLen: U = previousU = prf(password, salt + struct.pack('>I', i)) for j in xrange(count - 1): previousU = t = prf(password, previousU) U = strxor(U, t) key += U i = i + 1 return key[:dkLen]
def generate(dec, enc): while True: iv = get_random_bytes(16) if query(iv, enc): break actual = [] for i in range(16): tmp = list(iv) row = [] for c in range(256): tmp[i] = c row.append(query(bytes(tmp), enc)) if row.count(True) > row.count(False): row = [not x for x in row] try: if row.count(True) == 64: actual.append(table64.index(row)) else: actual.append(table65.index(row)) except: return generate(dec, enc) return strxor(dec, bytes(actual))
def ctr_aes_image(iv, image_file='image.ppm', out_file='my_enc_image.ppm', key_file='key.txt'): #Read keyfile kptr = open(key_file, "r") key = kptr.readline() key = key.strip() #Open PPM File bptr = open(image_file, "rb") wholeassfile = bptr.readlines() #Initializations header = wholeassfile[0:3] ppm = wholeassfile[3:len(wholeassfile)] bkey = bytes(key, 'utf-8') encodedarr = [] bvppm = [] for i in ppm: bv = BitVector(rawbytes=i) bvppm.append(bv) #convert IV to int, add one, convert back to bitvector #Start encoding kak = AES.new(bkey, AES.MODE_ECB) for i in ppm: ede1 = kak.encrypt(bytes.fromhex(iv.get_bitvector_in_hex())) print((len(ede1), len(i))) encodedarr.append(strxor(ede1, i)) #iv = BitVector(intVal= iv.int_val() + 1,size=128) tempwritetofile(header, encodedarr, 'poo.ppm') readprint('poo.ppm') readprint('enc_image.ppm')
def update(self, item): """Pass the next component of the vector. The maximum number of components you can pass is equal to the block length of the cipher (in bits) minus 1. :Parameters: item : byte string The next component of the vector. :Raise TypeError: when the limit on the number of components has been reached. :Raise ValueError: when the component is empty """ if not item: raise ValueError('A component cannot be empty') if self._n_updates == 0: raise TypeError('Too many components passed to S2V') self._n_updates -= 1 mac = CMAC.new(self._key, msg=self._last_string, ciphermod=self._ciphermod) self._cache = strxor(self._double(self._cache), mac.digest()) self._last_string = item
def cbc_encrypt(func, data, blocksize): ''' Uses func to encrypt data in CBC mode using a randomly generated IV. The IV is prefixed to the ciphertext. args: func: a function that encrypts data in ECB mode data: plaintext blocksize: block size of the cipher ''' assert len(data) % blocksize == 0 iv = os.urandom(blocksize) assert len(iv) == blocksize ciphertext = iv for block_index in range(len(data) // blocksize): xored = strxor(data[:blocksize], iv) enc = func(xored) ciphertext += enc iv = enc data = data[blocksize:] assert len(ciphertext) % blocksize == 0 return ciphertext
def cbc_encrypt(iv, aes_key, pfile): # iv - 16 random generated iv # aes_key - 16 byte key derived from user pass # pfile - string file name to read in chunks (in bytes) # return the ciphertext ciphertext = '' xoring = '' # create cipher object with key cipher = AES.new(aes_key) with open(pfile, 'r') as f: for chunk in read_chunk_aes(f): # read chunk by chunk xoring = strxor(iv, chunk) # xor iv and plaintext iv = cipher.encrypt(xoring) # encrypt the xor of iv and chunk ciphertext += cipher.encrypt( xoring) # encrypt the xor of iv and chunk f.close() # print ciphertext return ciphertext
def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen): emLen = ceil_div(emBits, 8) lmask = 0 for i in xrange(8 * emLen - emBits): lmask = lmask >> 1 | 128 if emLen < mhash.digest_size + sLen + 2: raise ValueError('Digest or salt length are too long for given key size.') salt = b('') if randFunc and sLen > 0: salt = randFunc(sLen) try: h = mhash.new(bchr(0) * 8 + mhash.digest() + salt) except AttributeError: h = Hash_new(mhash, bchr(0) * 8 + mhash.digest() + salt) db = bchr(0) * (emLen - sLen - mhash.digest_size - 2) + bchr(1) + salt dbMask = mgf(h.digest(), emLen - mhash.digest_size - 1) maskedDB = strxor(db, dbMask) maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:] em = maskedDB + h.digest() + bchr(188) return em
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): """Returns a binary digest for the PBKDF2 hash algorithm of `data` with the given `salt`. It iterates `iterations` time and produces a key of `keylen` bytes. By default SHA-1 is used as hash function, a different hashlib `hashfunc` can be provided. """ hashfunc = hashfunc or sha1 mac = hmac.new(data, None, hashfunc) def _pseudorandom(x, mac=mac): h = mac.copy() h.update(x) return h.digest() buf = deque() for block in xrange(1, -(-keylen // mac.digest_size) + 1): rv = u = _pseudorandom(salt + _pack_int(block)) for i in xrange(iterations - 1): u = _pseudorandom(u) rv = strxor(rv, u) buf.extend(rv) return ''.join(buf)[:keylen]
def retrieve_password(): global appdata global masterPwd # If the user chooses to access a previosly saved password URL = input( "Type the URL (or some other information) for the website (or service) associated with the account whose password you wish to access, and press ENTER. \nMake sure that what you enter here is the exact same text typed in when you originally saved the password you want to access.\n" ) username = input( "Now type the username associated with the password you want to access, and press ENTER.\n" ) # Compute a SHA-2 hash of the concatenated URL and username associated with that password, and search for this. hash = SHA256.new() hash.update((URL + '|' + username).encode()) infoHashed = hash.digest() # Parse appdata for infoHashed if infoHashed not in appdata: print( "We couldn't find that URL-username combination. You may have entered the information wrong, or you may not have had a password stored at that URL with the associated username." ) # If infoHashed is found, get salt and recreate one-time pad else: substring = appdata.split(infoHashed, 1)[1] salt = substring.split("||".encode(), 3)[1] ciphertext = substring.split("||".encode(), 3)[2] #Create one-time-pad using PBKDF2 (with masterPwd as password, salt as salt, dkLen as len(masterPwd), and count as 1000) one_time_pad = PBKDF2(masterPwd, salt, dkLen=len(masterPwd), count=1000) # XOR with one-time-pad to create plaintext password = strxor(ciphertext, one_time_pad).decode() # save the line under infoHashed as "salt," and the line under salt as "ciphertext" # Create one-time-pad using PBKDF2 (with masterPwd as password, salt as salt, dkLen as len(masterPwd), and count as 1000) # XOR this one-time-pad with ciphertext pyperclip.copy(password)
def digest(self): """Compute the *binary* MAC tag. The caller invokes this function at the very end. This method returns the MAC that shall be sent to the receiver, together with the ciphertext. :Return: the MAC, as a byte string. """ if self.digest not in self._next: raise TypeError("digest() cannot be called when decrypting" " or validating a message") self._next = [self.digest] if not self._mac_tag: tag = bchr(0) * self.block_size for i in xrange(3): tag = strxor(tag, self._omac[i].digest()) self._mac_tag = tag[:self._mac_len] return self._mac_tag
def challenge49_second_part(): from_id = 2 to_id = 3 amount = 10 msg = "from=#{%s}&tx_list=#{%s:%s(;%s:%s)}" % (from_id, to_id, to_id, amount, amount) print(msg) print len(msg) key = "1" * 16 mac1 = get_mac_fixed_iv(key, msg) # we have a message of two blocks m1 = msg[:16], m2 = msg[16:] # let's say msg_pad = pkcs7 padding for msg # mac(m1 || m2 || msg_pad || xor(m1, mac1) || m2) = mac(m1 || m2) padded_m = pkcs7_encode(msg) s = padded_m + strxor(msg[:16], mac1) + msg[16:] # now we know what mac has a message s and s contains more transactions than the original msg to be # executed, so we are able to send a rogue request print msg print s smac = get_mac_fixed_iv(key, s) print mac1 == smac
def oracle(shift, mask): mask = strxor(baseMaskForShift(shift), mask) setServerXorStream(mask) server.sendline(json.dumps({'action': 'decryption_check', 'params': {}})) msg = json.loads(server.readline()) try: secret_enc = msg['params']['secret'][0] except: print(msg) exit() payload = (secret_enc * pow(pow(2, shift, client_n), client_e, client_n)) % client_n client.sendline( json.dumps({ 'action': 'decryption_check_reply', 'params': { 'secret': [payload] } })) resp = json.loads(client.readline()) return resp['action'] == 'confirm_receipt'
def decrypt(self, ciphertext): """CBC decryption.""" cipher = AES.new(key=self._key, mode=AES.MODE_ECB) prev_ct = self._iv block_index = 0 plaintext = b'' # The loop simulates decryption through AES in CBC mode. while block_index < len(ciphertext): block = ciphertext[block_index:block_index + AES.block_size] prep_plaintext = cipher.decrypt(block) plaintext += strxor(prev_ct, prep_plaintext) prev_ct = block block_index += AES.block_size # Here we should check if this is all readable ASCII, and raise an # exception if it's not. However that part is not really necessary, # and converting from Exception object to byte string (instead of a # usual string) does not look great so let's be lazy :) return plaintext
def init (self, entropy, data=None): if len(entropy) != self.seedlen: raise ValueError('Entropy should be exachtly {} bytes long'.format( self.seedlen)) super(CTRDRBG, self).init(entropy, data) if data: if len(data) > self.seedlen: raise ValueError('Only {} bytes of data supported.'.format( self.seedlen)) delta = len(entropy) - len(data) if delta > 0: data = (b'\x00' * delta) + data seed_material = strxor(entropy, data) else: seed_material = entropy Key = b'\x00' * (self.keylen // 8) V = b'\x00' * (self.outlen // 8) self.__key, self.__V = self.__update(seed_material, Key, V)
def rsa_cbc_dencrypt(data, key): # extract iv from encrypted data IV = data[-128:] cipher_text = data[:-128] # split cipher text in chunks of 2*RSA Block size c = [] for i in xrange(0, len(cipher_text), 2 * RSA_BLOCK_SIZE): x = cipher_text[i:i + 2 * RSA_BLOCK_SIZE] c.append(x) # decrypt each chunk text = [] for d in c: dx = rsa_decrypt(d, key) # clear_text=sxor(dx, IV) clear_text = strxor.strxor(dx, IV) IV = d[0:128] text.append(clear_text) big_data = "".join(text) r = unpad(big_data) return r
def aes_key_unwrap(key, c): assert (len(c) % 8 == 0) n = len(c) / 8 - 1 r = range(n + 1) r[0] = b'\0\0\0\0\0\0\0\0' for i in range(1, n + 1): r[i] = c[i * 8:(i + 1) * 8] a = c[:8] aes = AESCipher(key) for j in range(5, -1, -1): for i in range(n, 0, -1): t = struct.pack("!q", (n * j) + i) a = strxor(a, t) b = aes.decrypt( a + r[i]) # B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i a = b[:8] # A = MSB(64, B) r[i] = b[8:] # R[i] = LSB(64, B) if (a == b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6'): return "".join(r[1:]) else: raise "Key unwrap integrity check failed"
key_size = (16, 24, 32) ''' # RSA print("RSA") import rsa key_size = 1024 (bob_pub, bob_priv) = rsa.newkeys(key_size) text = b"PIZZZZZZZZZZZZZZZzzzzzZZZzza" e = rsa.encrypt(text, bob_pub) print(e) d = rsa.decrypt(e, bob_priv) print(d) # Random (crypto secure) print("Random") from Crypto.Random.random import randint print(randint(0,100)) # String XOR print("String XOR") from Crypto.Util.strxor import strxor print(strxor(b'hii', b'bye'))
def RF(L, R, RK): md5 = MD5.new() md5.update(RK[0:1] + R + RK[1:2]) return strxor(L, md5.digest()), R
def encrypt(pfile, cfile): # benchmarking iter = benchmark() print "[+] Benchmark: %s PBKDF2 iterations in 1 second" % (iter) # asking for password print "[?] Enter password:"******"[+] Used Salt: "+salt.encode('hex')) pdbfk2 = PBKDF2(passwd, salt, 36, iter) #print("[+] Used Iteration Number: "+str(iter)) aes_key = pdbfk2[0:16] #print("[+] Used Aes_key: "+aes_key.encode('hex')) hmac_key = pdbfk2[16:36] #print("[+] Used Hmac_key: "+hmac_key.encode('hex')) myHmac = hmac.new(hmac_key, None, hashlib.sha1) # writing ciphertext in temporary file and calculating HMAC digest byte_chunk_size = 512 iv = os.urandom(16) #print("[+] Used IV: "+iv.encode('hex')) iv_used = False cipher = AES.new(aes_key) file = open(pfile) enc = '' res = '' temp = open("temp", mode='w+') while True: chunk = file.read(byte_chunk_size) if chunk == '': break padding = 16 - (len(chunk) % 16) chunk = chunk + chr(padding) * padding block = chunk[0:16] if (not iv_used): res = strxor(block, iv) enc = cipher.encrypt(res) iv_used = True else: res = strxor(block, enc) enc = cipher.encrypt(res) temp.write(enc) remaining = chunk[16:len(chunk)] for i in range(0, (len(remaining) / 16)): if remaining == '': break res = strxor(remaining[0:16], enc) enc = cipher.encrypt(res) temp.write(enc) remaining = remaining[16:len(remaining)] ###DO digest of ciphertext not password!!!! temp.close() digest_input = '' temp_read = open("temp") while True: chunk = temp_read.read(byte_chunk_size) if chunk == '': break digest_input += chunk myHmac.update(chunk) #print("[+] Digest Input: "+digest_input.encode('hex')) hmac_digest = myHmac.digest() #print("[+] Expected digest: "+hmac_digest.encode('hex')) # writing DER structure in cfile der_str = asn1_sequence( asn1_sequence( asn1_octetstring(salt) + asn1_integer(iter) + asn1_integer(36)) + asn1_sequence( asn1_objectidentifier([2, 16, 840, 1, 101, 3, 4, 1, 2]) + asn1_octetstring(iv)) + asn1_sequence( asn1_sequence( asn1_objectidentifier([1, 3, 14, 3, 2, 26]) + asn1_null()) + asn1_octetstring(hmac_digest))) cipherfile = open(cfile, mode='w+') cipherfile.write(der_str) #print("[+] Generated DER: "+der_str.encode('hex')) # writing temporary ciphertext file to cfile temp = open("temp") while True: chunk = temp.read(byte_chunk_size) if chunk == '': break cipherfile.write(chunk) cipherfile.close() test = open(cfile) # deleting temporary ciphertext file os.remove("temp") pass
import base64 from Crypto.Util.strxor import strxor key = "****" message = "****" assert len(key) == 14 strxor_key = "HelloCrypto" strxor_key = (strxor_key * (len(message) / len(strxor_key) + 1))[:len(message)] message = strxor(message, strxor_key) message += key cipher = '' for i in range(0, len(message)): cipher += chr( (ord(message[i]) + ord(key[i % len(key)]) + 0xDEADBEEF) % 128) print base64.b64encode(cipher.encode("hex"))
def decrypt(cfile, pfile): # reading DER structure cipherfile = open(cfile).read(2) der_len = int(cipherfile[1].encode('hex'), 16) #print("[+] Der length: "+str(der_len)) file = open(cfile) der_str = file.read(der_len + 2) decoded = decoder.decode(der_str) byte_chunk_size = 512 salt = str(decoded[0][0][0]) #print("[+] Obtained Salt: "+salt.encode('hex')) iter_n = int(str(decoded[0][0][1])) #print("[+] Obtained Iteration Number: "+str(iter_n)) key_len = int(str(decoded[0][0][2])) #print("[+] Obtained Key Length: "+str(key_len)) aes_id = str(decoded[0][1][0]) aes_iv = str(decoded[0][1][1]) #print("[+] Obtained IV: "+aes_iv.encode('hex')) hash_id = str(decoded[0][2][0][0]) digest_expected = str(decoded[0][2][1]) # asking for password print "[?] Enter password:"******"[+] Used AES key: "+aes_key.encode('hex')) hmac_key = pdbfk2[16:36] #print("[+] Used HMAC key: "+hmac_key.encode('hex')) myHmac = hmac.new(hmac_key, None, hashlib.sha1) readc = open(cfile) readc.read(der_len + 2) digest_input = '' while True: chunk = readc.read(byte_chunk_size) if chunk == '': break digest_input += chunk myHmac.update(chunk) #print("[+] Digest Input: "+digest_input.encode('hex')) digest_produced = myHmac.digest() #print("[+] Digest produced: "+digest_produced.encode('hex')) # first pass over ciphertext to calculate and verify HMAC if digest_expected != digest_produced: print( "[-] HMAC verification failure: wrong password or modified ciphertext!" ) return # second pass over ciphertext to decrypt byte_chunk_size = 512 iv = aes_iv cipher = AES.new(aes_key) plaintext = '' dec = '' res = '' writep = open(pfile, 'w') while True: chunk = file.read(byte_chunk_size) if chunk == '': break res = cipher.decrypt(chunk[0:16]) dec = strxor(res, iv) plaintext = plaintext + dec iv = chunk[0:16] chunk = chunk[16:len(chunk)] for i in range(0, (len(chunk) / 16)): res = cipher.decrypt(chunk[0:16]) dec = strxor(res, iv) plaintext = plaintext + dec iv = chunk[0:16] chunk = chunk[16:len(chunk)] padding_len = int(plaintext[len(plaintext) - 1].encode('hex'), 16) plaintext = plaintext[0:(len(plaintext) - padding_len)] while True: if plaintext == '': break writep.write(plaintext[0:byte_chunk_size]) plaintext = plaintext[byte_chunk_size:] pass
def decrypt(self, ciphertext): """Decrypt a message with PKCS#1 OAEP. :param ciphertext: The encrypted message. :type ciphertext: byte string/array :returns: The original message (plaintext). :rtype: byte string :raises ValueError: if the ciphertext has the wrong length, or if decryption fails the integrity check (in which case, the decryption key is probably wrong). :raises TypeError: if the RSA key has no private half (i.e. you are trying to decrypt using a public key). """ # See 7.1.2 in RFC3447 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes hLen = self._hashObj.digest_size # Step 1b and 1c if len(ciphertext) != k or k < hLen + 2: raise ValueError("Ciphertext with incorrect length.") # Step 2a (O2SIP) ct_int = bytes_to_long(bstr(ciphertext)) # Step 2b (RSADP) m_int = self._key._decrypt(ct_int) # Complete step 2c (I2OSP) em = long_to_bytes(m_int, k) # Step 3a lHash = self._hashObj.new(self._label).digest() # Step 3b y = em[0] # y must be 0, but we MUST NOT check it here in order not to # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143) maskedSeed = em[1:hLen + 1] maskedDB = em[hLen + 1:] # Step 3c seedMask = self._mgf(maskedDB, hLen) # Step 3d seed = strxor(maskedSeed, seedMask) # Step 3e dbMask = self._mgf(seed, k - hLen - 1) # Step 3f db = strxor(maskedDB, dbMask) # Step 3g valid = 1 one = db[hLen:].find(bchr(0x01)) lHash1 = db[:hLen] if lHash1 != lHash: valid = 0 if one < 0: valid = 0 if bord(y) != 0: valid = 0 if not valid: raise ValueError("Incorrect decryption.") # Step 4 return db[hLen + one + 1:]
def __next__(self): ts = datetime.now().strftime('%S%f') T = self.cipher.encrypt(ts) out = self.cipher.encrypt(strxor(T, self.__state)) self.__state = self.cipher.encrypt(strxor(T, out)) return out.hex()
from Crypto.Util import strxor m = "Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal" key = "ICE" * 1000 print strxor.strxor(m, key[:len(m)]).encode('hex')
def decrypt(self, ct): """Decrypt a PKCS#1 OAEP ciphertext. This function is named ``RSAES-OAEP-DECRYPT``, and is specified in section 7.1.2 of RFC3447. :Parameters: ct : string The ciphertext that contains the message to recover. :Return: A string, the original message. :Raise ValueError: If the ciphertext length is incorrect, or if the decryption does not succeed. :Raise TypeError: If the RSA key has no private half. """ # TODO: Verify the key is RSA # See 7.1.2 in RFC3447 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes hLen = self._hashObj.digest_size # Step 1b and 1c if len(ct) != k or k < hLen + 2: raise ValueError("Ciphertext with incorrect length.") # Step 2a (O2SIP), 2b (RSADP), and part of 2c (I2OSP) m = self._key.decrypt(ct) # Complete step 2c (I2OSP) em = bchr(0x00) * (k - len(m)) + m # Step 3a lHash = self._hashObj.new(self._label).digest() # Step 3b y = em[0] # y must be 0, but we MUST NOT check it here in order not to # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143) maskedSeed = em[1:hLen + 1] maskedDB = em[hLen + 1:] # Step 3c seedMask = self._mgf(maskedDB, hLen) # Step 3d seed = strxor(maskedSeed, seedMask) # Step 3e dbMask = self._mgf(seed, k - hLen - 1) # Step 3f db = strxor(maskedDB, dbMask) # Step 3g valid = 1 one = db[hLen:].find(bchr(0x01)) lHash1 = db[:hLen] if lHash1 != lHash: valid = 0 if one < 0: valid = 0 if bord(y) != 0: valid = 0 if not valid: raise ValueError("Incorrect decryption.") # Step 4 return db[hLen + one + 1:]
def bs(word, sum_chunk): bin_string = bin(int(sum_chunk, 16))[2:].zfill(len(word)).replace( "1", " ").replace("0", "\0") return strxor(word, bin_string)