def _start_mac(self): assert(self._mac_status == MacStatus.NOT_STARTED) assert(None not in (self._assoc_len, self._msg_len)) assert(isinstance(self._cache, list)) # Formatting control information and nonce (A.2.1) q = 15 - len(self.nonce) # length of Q, the encoded message length flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) + (q - 1)) b_0 = bchr(flags) + self.nonce + long_to_bytes(self._msg_len, q) # Formatting associated data (A.2.2) # Encoded 'a' is concatenated with the associated data 'A' assoc_len_encoded = b('') if self._assoc_len > 0: if self._assoc_len < (2 ** 16 - 2 ** 8): enc_size = 2 elif self._assoc_len < (2L ** 32): assoc_len_encoded = b('\xFF\xFE') enc_size = 4 else: assoc_len_encoded = b('\xFF\xFF') enc_size = 8 assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size)
def decrypt(self, init_value, ciphertext, auth_tag, auth_data=b''): if init_value >= (1 << 96): raise InvalidInputException('IV should be 96-bit') if auth_tag >= (1 << 128): raise InvalidInputException('Tag should be 128-bit') if auth_tag != self.__ghash( auth_data, ciphertext) ^ bytes_to_long( self._aes_ecb.encrypt( long_to_bytes((init_value << 32) | 1, 16))): raise InvalidTagException len_ciphertext = len(ciphertext) if len_ciphertext > 0: counter = Counter.new( nbits=32, prefix=long_to_bytes(init_value, 12), initial_value=2, allow_wraparound=True) aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter) if 0 != len_ciphertext % 16: padded_ciphertext = ciphertext + \ b'\x00' * (16 - len_ciphertext % 16) else: padded_ciphertext = ciphertext plaintext = aes_ctr.decrypt(padded_ciphertext)[:len_ciphertext] else: plaintext = b'' return plaintext
def _start_mac(self): assert(self._mac_status == MacStatus.NOT_STARTED) assert(None not in (self._assoc_len, self._msg_len)) assert(isinstance(self._cache, list)) # Formatting control information and nonce (A.2.1) q = 15 - len(self.nonce) # length of Q, the encoded message length flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) + (q - 1)) b_0 = struct.pack("B", flags) + self.nonce + long_to_bytes(self._msg_len, q) # Formatting associated data (A.2.2) # Encoded 'a' is concatenated with the associated data 'A' assoc_len_encoded = b'' if self._assoc_len > 0: if self._assoc_len < (2 ** 16 - 2 ** 8): enc_size = 2 elif self._assoc_len < (2 ** 32): assoc_len_encoded = b'\xFF\xFE' enc_size = 4 else: assoc_len_encoded = b'\xFF\xFF' enc_size = 8 assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size) # b_0 and assoc_len_encoded must be processed first self._cache.insert(0, b_0) self._cache.insert(1, assoc_len_encoded) # Process all the data cached so far first_data_to_mac = b"".join(self._cache) self._cache = b"" self._mac_status = MacStatus.PROCESSING_AUTH_DATA self._update(first_data_to_mac)
def test3(self): for keylen, taglen, result in self.tv3: key = bchr(0) * (keylen // 8 - 1) + bchr(taglen) C = b("") for i in range(128): S = bchr(0) * i N = long_to_bytes(3 * i + 1, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) cipher.update(S) C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest() N = long_to_bytes(3 * i + 2, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest() N = long_to_bytes(3 * i + 3, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) cipher.update(S) C += cipher.encrypt() + cipher.digest() N = long_to_bytes(385, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) cipher.update(C) result2 = cipher.encrypt() + cipher.digest() self.assertEquals(unhexlify(b(result)), result2)
def sign(self, msg_hash): """Create the PKCS#1 v1.5 signature of a message. This function is also called ``RSASSA-PKCS1-V1_5-SIGN`` and it is specified in `section 8.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-36>`_. :parameter msg_hash: This is an object from the :mod:`Cryptodome.Hash` package. It has been used to digest the message to sign. :type msg_hash: hash object :return: the signature encoded as a *byte string*. :raise ValueError: if the RSA key is not long enough for the given hash algorithm. :raise TypeError: if the RSA key has no private half. """ # See 8.2.1 in RFC3447 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes # Step 1 em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k) # Step 2a (OS2IP) em_int = bytes_to_long(em) # Step 2b (RSASP1) m_int = self._key._decrypt(em_int) # Step 2c (I2OSP) signature = long_to_bytes(m_int, k) return signature
def to_bytes(self, block_size=0): if self._value < 0: raise ValueError("Conversion only valid for non-negative numbers") result = long_to_bytes(self._value, block_size) if len(result) > block_size > 0: raise ValueError("Value too large to encode") return result
def sign(self, msg_hash): """Produce the PKCS#1 v1.5 signature of a message. This function is named ``RSASSA-PKCS1-V1_5-SIGN``; it is specified in section 8.2.1 of RFC3447. :Parameters: msg_hash : hash object This is an object created with to the `Cryptodome.Hash` module. It was used used to hash the message to sign. :Return: The signature encoded as a byte string. :Raise ValueError: If the RSA key is not long enough when combined with the given hash algorithm. :Raise TypeError: If the RSA key has no private half. """ # See 8.2.1 in RFC3447 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes # Step 1 em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k) # Step 2a (OS2IP) em_int = bytes_to_long(em) # Step 2b (RSASP1) m_int = self._key._decrypt(em_int) # Step 2c (I2OSP) signature = long_to_bytes(m_int, k) return signature
def _compute_mac(self): """Compute MAC without any FSM checks.""" if self._tag: return self._tag # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S self._pad_cache_and_update() self._update(long_to_bytes(8 * self._auth_len, 8)) self._update(long_to_bytes(8 * self._msg_len, 8)) s_tag = self._signer.digest() # Step 6 - Compute T self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len] return self._tag
def MGF1(mgfSeed, maskLen, hash_gen): """Mask Generation Function, described in `B.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017>`_. :param mfgSeed: seed from which the mask is generated :type mfgSeed: byte string :param maskLen: intended length in bytes of the mask :type maskLen: integer :param hash_gen: A module or a hash object from :mod:`Cryptodome.Hash` :type hash_object: :return: the mask, as a *byte string* """ T = b"" for counter in iter_range(ceil_div(maskLen, hash_gen.digest_size)): c = long_to_bytes(counter, 4) hobj = hash_gen.new() hobj.update(mgfSeed + c) T = T + hobj.digest() assert(len(T) >= maskLen) return T[:maskLen]
def _definite_form(length): """Build length octets according to BER/DER definite form. """ if length > 127: encoding = long_to_bytes(length) return bchr(len(encoding) + 128) + encoding return bchr(length)
def inplace_pow(self, exponent, modulus=None): exp_value = int(exponent) if exp_value < 0: raise ValueError("Exponent must not be negative") # No modular reduction if modulus is None: self._value = pow(self._value, exp_value) return self # With modular reduction mod_value = int(modulus) if mod_value < 0: raise ValueError("Modulus must be positive") if mod_value == 0: raise ZeroDivisionError("Modulus cannot be zero") # C extension only works with odd moduli if (mod_value & 1) == 0: self._value = pow(self._value, exp_value, mod_value) return self max_len = len(long_to_bytes(max(self._value, exp_value, mod_value))) base_b = long_to_bytes(self._value, max_len) exp_b = long_to_bytes(exp_value, max_len) modulus_b = long_to_bytes(mod_value, max_len) out = create_string_buffer(max_len) error = _raw_montgomery.monty_pow( base_b, exp_b, modulus_b, out, c_size_t(max_len), c_ulonglong(getrandbits(64)) ) if error: raise ValueError("monty_pow failed with error: %d" % error) result = bytes_to_long(get_raw_buffer(out)) self._value = result return self
def MGF1(mgfSeed, maskLen, hash): """Mask Generation Function, described in B.2.1""" T = b("") for counter in xrange(ceil_div(maskLen, hash.digest_size)): c = long_to_bytes(counter, 4) hobj = hash.new() hobj.update(mgfSeed + c) T = T + hobj.digest() assert(len(T) >= maskLen) return T[:maskLen]
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 : byte 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 byte 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 # See 7.1.1 in RFC3447 modBits = Cryptodome.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 = 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 = bchr(0x00) + 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 verify(self, msg_hash, signature): """Verify that a certain PKCS#1 v1.5 signature is valid. This method checks if the message really originates from someone that holds the RSA private key. really signed the message. This function is named ``RSASSA-PKCS1-V1_5-VERIFY``; it is specified in section 8.2.2 of RFC3447. :Parameters: msg_hash : hash object The hash that was carried out over the message. This is an object belonging to the `Cryptodome.Hash` module. signature : byte string The signature that needs to be validated. :Raise ValueError: if the signature is not valid. """ # See 8.2.2 in RFC3447 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes # Step 1 if len(signature) != k: raise ValueError("Invalid signature") # Step 2a (O2SIP) signature_int = bytes_to_long(signature) # Step 2b (RSAVP1) em_int = self._key._encrypt(signature_int) # Step 2c (I2OSP) em1 = long_to_bytes(em_int, k) # Step 3 try: possible_em1 = [ _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, True) ] # MD2/4/5 hashes always require NULL params in AlgorithmIdentifier. # For all others, it is optional. try: algorithm_is_md = msg_hash.oid.startswith('1.2.840.113549.2.') except AttributeError: algorithm_is_md = False if not algorithm_is_md: # MD2/MD4/MD5 possible_em1.append(_EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, False)) except ValueError: raise ValueError("Invalid signature") # Step 4 # By comparing the full encodings (as opposed to checking each # of its components one at a time) we avoid attacks to the padding # scheme like Bleichenbacher's (see http://www.mail-archive.com/[email protected]/msg06537). # if em1 not in possible_em1: raise ValueError("Invalid signature") pass
def _compute_mac(self): """Finalize the cipher (if not done already) and return the MAC.""" if self._mac_tag: assert(self._status == _CipherStatus.PROCESSING_DONE) return self._mac_tag assert(self._status != _CipherStatus.PROCESSING_DONE) if self._status == _CipherStatus.PROCESSING_AUTH_DATA: self._pad_aad() if self._len_ct & 0x0F: self._authenticator.update(b'\x00' * (16 - (self._len_ct & 0x0F))) self._status = _CipherStatus.PROCESSING_DONE self._authenticator.update(long_to_bytes(self._len_aad, 8)[::-1]) self._authenticator.update(long_to_bytes(self._len_ct, 8)[::-1]) self._mac_tag = self._authenticator.digest() return self._mac_tag
def testVerify2(self): # Verify that decryption fails if ciphertext is not as long as # RSA modulus cipher = PKCS.new(self.key1024) self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---") self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---") # Verify that decryption fails if there are less then 8 non-zero padding # bytes pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118) pt_int = bytes_to_long(pt) ct_int = self.key1024._encrypt(pt_int) ct = long_to_bytes(ct_int, 128) self.assertEqual("---", cipher.decrypt(ct, "---"))
def monty_pow(base, exp, modulus): max_len = len(long_to_bytes(max(base, exp, modulus))) base_b, exp_b, modulus_b = [ long_to_bytes(x, max_len) for x in (base, exp, modulus) ] out = create_string_buffer(max_len) error = _raw_montgomery.monty_pow( base_b, exp_b, modulus_b, out, c_size_t(max_len), c_ulonglong(32) ) if error == 2: raise ExceptionModulus() if error: raise ValueError("monty_pow failed with error: %d" % error) result = bytes_to_long(get_raw_buffer(out)) return result
def encrypt(self, init_value, plaintext, auth_data=b''): if init_value >= (1 << 96): raise InvalidInputException('IV should be 96-bit') # a naive checking for IV reuse if init_value == self.prev_init_value: raise InvalidInputException('IV must not be reused!') self.prev_init_value = init_value len_plaintext = len(plaintext) # len_auth_data = len(auth_data) if len_plaintext > 0: counter = Counter.new( nbits=32, prefix=long_to_bytes(init_value, 12), initial_value=2, # notice this allow_wraparound=True) aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter) if 0 != len_plaintext % 16: padded_plaintext = plaintext + \ b'\x00' * (16 - len_plaintext % 16) else: padded_plaintext = plaintext ciphertext = aes_ctr.encrypt(padded_plaintext)[:len_plaintext] else: ciphertext = b'' auth_tag = self.__ghash(auth_data, ciphertext) # print 'GHASH\t', hex(auth_tag) auth_tag ^= bytes_to_long(self._aes_ecb.encrypt( long_to_bytes((init_value << 32) | 1, 16))) # assert len(ciphertext) == len(plaintext) assert auth_tag < (1 << 128) return ciphertext, auth_tag
def sign(self, msg_hash): """Produce the PKCS#1 PSS signature of a message. This function is named ``RSASSA-PSS-SIGN``, and is specified in section 8.1.1 of RFC3447. :Parameters: msg_hash : hash object The hash that was carried out over the message. This is an object belonging to the `Cryptodome.Hash` module. :Return: The PSS signature encoded as a byte string. :Raise ValueError: If the RSA key length is not sufficiently long to deal with the given hash algorithm. :Raise TypeError: If the RSA key has no private half. :attention: Modify the salt length and the mask generation function only if you know what you are doing. The receiver must use the same parameters too. """ # Set defaults for salt length and mask generation function if self._saltLen is None: sLen = msg_hash.digest_size else: sLen = self._saltLen if self._mgfunc is None: mgf = lambda x, y: MGF1(x, y, msg_hash) else: mgf = self._mgfunc modBits = Cryptodome.Util.number.size(self._key.n) # See 8.1.1 in RFC3447 k = ceil_div(modBits, 8) # k is length in bytes of the modulus # Step 1 em = _EMSA_PSS_ENCODE(msg_hash, modBits-1, self._randfunc, mgf, sLen) # Step 2a (OS2IP) em_int = bytes_to_long(em) # Step 2b (RSASP1) m_int = self._key._decrypt(em_int) # Step 2c (I2OSP) signature = long_to_bytes(m_int, k) return signature
def encrypt(self, message): """Produce the PKCS#1 v1.5 encryption of a message. This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in `section 7.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-28>`_. :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 11. :type message: bytes/bytearray/memoryview :Returns: A byte string, the ciphertext in which the message is encrypted. It is as long as the RSA modulus (in bytes). :Raises ValueError: If the RSA key length is not sufficiently long to deal with the given message. """ # See 7.2.1 in RFC8017 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes mLen = len(message) # Step 1 if mLen > k - 11: raise ValueError("Plaintext is too long.") # Step 2a ps = [] while len(ps) != k - mLen - 3: new_byte = self._randfunc(1) if bord(new_byte[0]) == 0x00: continue ps.append(new_byte) ps = b"".join(ps) assert(len(ps) == k - mLen - 3) # Step 2b em = b'\x00\x02' + ps + b'\x00' + _copy_bytes(None, None, message) # 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 verify(self, msg_hash, signature): """Verify that a certain PKCS#1 PSS signature is authentic. This function checks if the party holding the private half of the given RSA key has really signed the message. This function is called ``RSASSA-PSS-VERIFY``, and is specified in section 8.1.2 of RFC3447. :Parameters: msg_hash : hash object The cryptographic hash computed over the message. This is an object belonging to the `Cryptodome.Hash` module. signature : byte string The signature that needs to be validated. :Raise ValueError: if the signature is incorrect. """ # Set defaults for salt length and mask generation function if self._saltLen is None: sLen = msg_hash.digest_size else: sLen = self._saltLen if self._mgfunc: mgf = self._mgfunc else: mgf = lambda x, y: MGF1(x, y, msg_hash) modBits = Cryptodome.Util.number.size(self._key.n) # See 8.1.2 in RFC3447 k = ceil_div(modBits, 8) # Convert from bits to bytes # Step 1 if len(signature) != k: raise ValueError("Incorrect signature") # Step 2a (O2SIP) signature_int = bytes_to_long(signature) # Step 2b (RSAVP1) em_int = self._key._encrypt(signature_int) # Step 2c (I2OSP) emLen = ceil_div(modBits - 1, 8) em = long_to_bytes(em_int, emLen) # Step 3/4 _EMSA_PSS_VERIFY(msg_hash, em, modBits-1, mgf, sLen)
def encrypt(self, message): """Produce the PKCS#1 v1.5 encryption of a message. This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and is specified in section 7.2.1 of RFC3447. For a complete example see `Cryptodome.Cipher.PKCS1_v1_5`. :Parameters: message : byte 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 11. :Return: A byte 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. """ # See 7.2.1 in RFC3447 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes mLen = len(message) # Step 1 if mLen > k-11: raise ValueError("Plaintext is too long.") # Step 2a ps = [] while len(ps) != k - mLen - 3: new_byte = self._randfunc(1) if bord(new_byte[0]) == 0x00: continue ps.append(new_byte) ps = b("").join(ps) assert(len(ps) == k - mLen - 3) # Step 2b em = b('\x00\x02') + ps + bchr(0x00) + message # 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 verify(self, msg_hash, signature): """Check if the PKCS#1 PSS signature over a message is valid. This function is also called ``RSASSA-PSS-VERIFY`` and it is specified in `section 8.1.2 of RFC8037 <https://tools.ietf.org/html/rfc8017#section-8.1.2>`_. :parameter msg_hash: The hash that was carried out over the message. This is an object belonging to the :mod:`Cryptodome.Hash` module. :type parameter: hash object :parameter signature: The signature that needs to be validated. :type signature: byte string :raise ValueError: if the signature is not valid. """ # Set defaults for salt length and mask generation function if self._saltLen is None: sLen = msg_hash.digest_size else: sLen = self._saltLen if self._mgfunc: mgf = self._mgfunc else: mgf = lambda x, y: MGF1(x, y, msg_hash) modBits = Cryptodome.Util.number.size(self._key.n) # See 8.1.2 in RFC3447 k = ceil_div(modBits, 8) # Convert from bits to bytes # Step 1 if len(signature) != k: raise ValueError("Incorrect signature") # Step 2a (O2SIP) signature_int = bytes_to_long(signature) # Step 2b (RSAVP1) em_int = self._key._encrypt(signature_int) # Step 2c (I2OSP) emLen = ceil_div(modBits - 1, 8) em = long_to_bytes(em_int, emLen) # Step 3/4 _EMSA_PSS_VERIFY(msg_hash, em, modBits-1, mgf, sLen)
def change_key(self, master_key): # RLB: Need to allow 192-, 256-bit keys # if master_key >= (1 << 128): # raise InvalidInputException('Master key should be 128-bit') self._master_key = long_to_bytes(master_key, 16) self._aes_ecb = AES.new(self._master_key, AES.MODE_ECB) self._auth_key = bytes_to_long(self._aes_ecb.encrypt(b'\x00' * 16)) # precompute the table for multiplication in finite field table = [] # for 8-bit for i in range(16): row = [] for j in range(256): row.append(gf_2_128_mul(self._auth_key, j << (8 * i))) table.append(tuple(row)) self._pre_table = tuple(table) self.prev_init_value = None # reset
def sign(self, msg_hash): """Produce the DSS signature of a message. :Parameters: msg_hash : hash object The hash that was carried out over the message. The object belongs to the `Cryptodome.Hash` package. Under mode *'fips-186-3'*, the hash must be a FIPS approved secure hash (SHA-1 or a member of the SHA-2 family), of cryptographic strength appropriate for the DSA key. For instance, a 3072/256 DSA key can only be used in combination with SHA-512. :Return: The signature encoded as a byte string. :Raise ValueError: If the hash algorithm is incompatible to the DSA key. :Raise TypeError: If the DSA key has no private half. """ if not self._valid_hash(msg_hash): raise ValueError("Hash is not sufficiently strong") # Generate the nonce k (critical!) nonce = self._compute_nonce(msg_hash) # Perform signature using the raw API z = Integer.from_bytes(msg_hash.digest()[:self._order_bytes]) sig_pair = self._key._sign(z, nonce) # Encode the signature into a single byte string if self._encoding == 'binary': output = b("").join([long_to_bytes(x, self._order_bytes) for x in sig_pair]) else: # Dss-sig ::= SEQUENCE { # r OCTET STRING, # s OCTET STRING # } output = DerSequence(sig_pair).encode() return output
def sign(self, msg_hash): """Create the PKCS#1 PSS signature of a message. This function is also called ``RSASSA-PSS-SIGN`` and it is specified in `section 8.1.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#section-8.1.1>`_. :parameter msg_hash: This is an object from the :mod:`Cryptodome.Hash` package. It has been used to digest the message to sign. :type msg_hash: hash object :return: the signature encoded as a *byte string*. :raise ValueError: if the RSA key is not long enough for the given hash algorithm. :raise TypeError: if the RSA key has no private half. """ # Set defaults for salt length and mask generation function if self._saltLen is None: sLen = msg_hash.digest_size else: sLen = self._saltLen if self._mgfunc is None: mgf = lambda x, y: MGF1(x, y, msg_hash) else: mgf = self._mgfunc modBits = Cryptodome.Util.number.size(self._key.n) # See 8.1.1 in RFC3447 k = ceil_div(modBits, 8) # k is length in bytes of the modulus # Step 1 em = _EMSA_PSS_ENCODE(msg_hash, modBits-1, self._randfunc, mgf, sLen) # Step 2a (OS2IP) em_int = bytes_to_long(em) # Step 2b (RSASP1) m_int = self._key._decrypt(em_int) # Step 2c (I2OSP) signature = long_to_bytes(m_int, k) return signature
def enc_setup(self, enc_alg, msg, auth_data, key=None, iv=""): """ Encrypt JWE content. :param enc_alg: The JWE "enc" value specifying the encryption algorithm :param msg: The plain text message :param auth_data: Additional authenticated data :param key: Key (CEK) :return: Tuple (ciphertext, tag), both as bytes """ key, iv = self._generate_key_and_iv(enc_alg, key, iv) if enc_alg in ["A192GCM", "A128GCM", "A256GCM"]: gcm = AES_GCM(bytes_to_long(key)) ctxt, tag = gcm.encrypt(bytes_to_long(iv), msg, auth_data) tag = long_to_bytes(tag) elif enc_alg in ["A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512"]: assert enc_alg in SUPPORTED["enc"] ctxt, tag = aes_cbc_hmac_encrypt(key, iv, auth_data, msg) else: raise NotSupportedAlgorithm(enc_alg) return ctxt, tag, key
def _length_encode(x): if x == 0: return b'\x00' S = long_to_bytes(x) return S + bchr(len(S))
def decrypt(self, ciphertext): """Decrypt a message with PKCS#1 OAEP. :param ciphertext: The encrypted message. :type ciphertext: bytes/bytearray/memoryview :returns: The original message (plaintext). :rtype: bytes :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 = Cryptodome.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(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 one_pos = db[hLen:].find(b'\x01') lHash1 = db[:hLen] invalid = bord(y) | int(one_pos < 0) hash_compare = strxor(lHash1, lHash) for x in hash_compare: invalid |= bord(x) for x in db[hLen:one_pos]: invalid |= bord(x) if invalid != 0: raise ValueError("Incorrect decryption.") # Step 4 return db[hLen + one_pos + 1:]
#!/usr/bin/env python3 from Cryptodome.Util import number import gmpy n = 17258212916191948536348548470938004244269544560039009244721959293554822498047075403658429865201816363311805874117705688359853941515579440852166618074161313773416434156467811969628473425365608002907061241714688204565170146117869742910273064909154666642642308154422770994836108669814632309362483307560217924183202838588431342622551598499747369771295105890359290073146330677383341121242366368309126850094371525078749496850520075015636716490087482193603562501577348571256210991732071282478547626856068209192987351212490642903450263288650415552403935705444809043563866466823492258216747445926536608548665086042098252335883 e = 3 ct = 243251053617903760309941844835411292373350655973075480264001352919865180151222189820473358411037759381328642957324889519192337152355302808400638052620580409813222660643570085177957 # n is a prime, e is small, ct is smaller than n print(number.long_to_bytes(gmpy.root(ct, e)[0]))
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 = bstr(nonce) """Nonce used for this session.""" if len(nonce) not in range(1, 16): raise ValueError("Nonce must be at most 15 bytes long") if isinstance(nonce, unicode): raise TypeError("Nonce must be a byte string") 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 int2bytes(self, x): return long_to_bytes(x, self.bytes)
def encode(self): """Return the field element, encoded as a 16 byte string.""" return long_to_bytes(self._value, 16)
# reference https://luniverse.io/cryptography-101-rsa-algorithm/?lang=ko import Cryptodome.Util.number as number e = 3 c = 219878849218803628752496734037301843801487889344508611639028 n = 245841236512478852752909734912575581815967630033049838269083 # factorize n @ http://factordb.com/index.php?query=245841236512478852752909734912575581815967630033049838269083 p = 416064700201658306196320137931 q = 590872612825179551336102196593 # calculate phi(n) and d phi = (q - 1) * (p - 1) d = number.inverse(e, phi) # plaintext: M = Cрхѕ (mod n) print(number.long_to_bytes(pow(c, d, n)))
def _int2octets(self, int_mod_q): """See 2.3.3 in RFC6979""" assert 0 < int_mod_q < self._order return long_to_bytes(int_mod_q, self._order_bytes)
#!/usr/bin/env python3 from Cryptodome.Util import number expected = 0x685f624f7d4563444f522b47297568286a6c2c764c expected = number.long_to_bytes(expected) def decrypt(): buf = [0] * len(expected) arr = [0] * 6 arr[0] = 0x10 arr[1] = 0x18 arr[2] = len(buf) >> 1 arr[3] = len(buf) arr[4] = 0 arr[5] = len(buf) >> 1 for i in range(2): cur = arr[i + 4] while cur < arr[i + 2]: buf[cur] = expected[cur] ^ arr[i] cur = cur + 1 return ''.join(map(chr, buf)) print(decrypt())
def _double(self, bs): doubled = bytes_to_long(bs)<<1 if bord(bs[0]) & 0x80: doubled ^= 0x87 return long_to_bytes(doubled, len(bs))[-len(bs):]
def rsa_encrypt(cls, data: bytes, key: bytes) -> bytes: rsa_key = RSA.import_key(key) return long_to_bytes( rsa_key._encrypt( bytes_to_long(pad_for_encryption(data, rsa_key.size_in_bytes()))))
def _shift_bytes(bs, xor_lsb=0): num = (bytes_to_long(bs) << 1) ^ xor_lsb return long_to_bytes(num, len(bs))[-len(bs):]
#!/usr/bin/env python3 from Cryptodome.Util.number import bytes_to_long, long_to_bytes UMAX = 256**16 def pad(block): return b"\x00" * (16 - len(block)) + block data = open("body.enc", "rb").read() img = b"" for i in range(16, len(data), 16): img += pad( long_to_bytes( bytes_to_long(data[i:i + 16]) - bytes_to_long(data[i - 16:i]) % UMAX)) open("body.ecb.ppm", "wb").write(b"P6\n1895 820\n255\n" + img)
#!/usr/bin/env python3 import gmpy2 from gmpy2 import mpfr from Cryptodome.Util.number import long_to_bytes gmpy2.get_context().precision = 1000 c = 2205316413931134031074603746928247799030155221252519872650082343781881947286623459260358458095368337105247516735006016223547924074432814737081052371203373104854490121754016011241903971190586239974732476290129461147622505210058893325312869 print(long_to_bytes(int(gmpy2.cbrt(c))).decode('utf-8'))
break return data.decode() conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((HOST, PORT)) conn.send(b'0' * 64 + b'\n') res = "" messages = [*filter(lambda x: len(x) == 64, recvall(conn).split('\n'))] for m in messages: if m[:32] == m[32:]: res += "1" else: res += "0" print(long_to_bytes(int(res[::-1], 2)).decode()) #EFIENSCTF{Now_you_know_ECB_is_weak_;)_} ''' # alternative way # run $python -c 'print("0"*64+"\n")' | nc 128.199.234.122 3333 > outcbc.txt f = open(os.path.join(os.sys.path[0], "outcbc.txt"), "r") messages = f.readlines() res = "" for m in messages: if m[:32] == m[32:-1]: res += "1" else: res += "0" print(long_to_bytes(int(res[::-1], 2)))
def bhex(s,sep=""): return hexdump(long_to_bytes(s,30),sep)
#!/usr/bin/env python3 from Cryptodome.Util.number import long_to_bytes f = open('whitepages.txt', 'rb').read() out = "" i = 0 while i < len(f): if f[i:i + 1] == b'\x20': out += "1" elif f[i:i + 3] == b'\xe2\x80\x83': out += "0" i += 2 i += 1 print(long_to_bytes(int(out, 2)).decode('utf-8'))
#!/usr/bin/env python3 from Cryptodome.Util import number n = 1063494238636905330671898279123020701722241177838742822812173978727720269828464796177466331816675300997219760473399150899338190503499441304612339501295713174906319744094945565844664372365921409430229356934682156557249826723147031652843433859344718768493183522524995480377138743798310313783408725321419870843554822150601536373735923419276343616677440442774544203945706641152517137477442684440329779076981535293867470891276594740058202983415251883426242386508849130959905432961654910957147313116759921173654729071152981682554792584462863534617943384988632032130835087976957452863581161399454295389753849954195624356779281196493728732643445649356033158461867533398892265000228558146288424480232820613034689816560319929705959290376265550914058448343308161173100473161643834475548888676356572581129193395124610558172636505697071928778350452726229098387020587814634712035171712313035012109421792643188405752849278190287414108308734638519593282032082768153331276317440224645157072560878195004847185217741752846484430459047014205368551175641186962966731731946128786111994668528579102737764964521437485037695161775036622411218739549286577109028626220150452705854596994751235894610227300222070678106023292138580496517177268042770934391185798181598618563332872419401223903806812404310665174941843727792999745655534108889130325189241267039092501129173520194489329592776789648244263220437261594447066833175026748830694496235756029688061559449109400248449366143822446893851310444152168531390880512280359096438303124398155397910138799660941243464476642041104225318910175143988510614445494598098558426300612294667831401095538851181871031466580808942102239297182977785401087460226345045290147371931284725756179151791539310603340196586480494033673522637677423221202352493653286430691931273676649062037570851083535722738207802574643773975006788646467981693396925922930573766914743566111012462215653872417726475122775377641591778444141816733462035690735543990556767891443301312941168828619850007793197693295002346977318117653857994731382292035666024397790972920502626243999541832942059274728220802530163223188484361653845185336386588669397688474323385816925410493569923865462650449548121898936835205060632513390578074550881170405889665319159308800795056447244869407145217360018494614236328487464266591617854909647808315406639117270321158016494893469025866752746911948790708005075752364953010067274475470453957941422189404716860354111166203043679764568407375052809648827400302926099178569 e = 322080206518256091443899533297838582806903462189212623492459529527398362853578807723331748892091281476489691674322396825893568981731186597175657851460964692083587224231830304595753200276915353388440323973696723177120007866661510911934423352216586106031397002127519163858107192766128665700540985814443511274004469695128927172454976219787146706562954392698315026949257322529441349029783228167181158744356828575460114272675952388130344874175195393881248661753342888300368969470477541152888408256683251028110005741172636776279619483668723660512026112365800539035538500635904281702733475127339140385714006560153071610279780303018848372325359598739283968138816333125764253403325773002607652913882484078902775827169048401031393263955166695217841400017855979724317225872294531492451624247032809524082714281043873127461832051383511298796820369453358960824162684362741938604084210435623099328622028419710290325683380378726085007158903982932912214314158223921219724759717266136246703830446993309980595073110001804483058339461412460693911416430728558495048873597685942089531373734578638349738930086910038003088294940942692030998047041393152747526278088574238755027474019265539054527491401757165011505470582647900401492273402847703170162847259159161319094910753659832147964969052296859561769298825881593753592121708897035728873795159475926749806998737812501868665513946666352941497086651818553871606417281352599234688183547212675353626023151426982640664474136377374110023532481101565870359846621748326349516467938614155834462639061592390266451169971250010491497379073868786106821570448253182042906240682833067783409574735400739329311810053094530811477002973464432651755811246151509011287858077298295987954915889199100328695730233096226912526329144478198121096489396083876129542516602969866961376423685647767885680559757094208574124411496017291060228388949556065235333802142865557844913535276572535282671404020237763405558477020152910105019008364237315330047605257380696367871417207254833979064342650664181309067142909106945469319731754805506564282047041605728503555870882010025649797753726253285119740979484849951129514070748168270413416940958393138417596025358589062839735425553556206423183484639265605269615685651949641759227283257819425264608389110223455267792764547470141745830149226062457331548317230637497633273069300415564503833751637575125936072041989787691982221885384446295804003751739608564016981200019839941768866474797817202494560129096305497153712068566001154013937 c = 329889278578044016824313741527705229624826354380113199851837764563746872233807021113693371778072747023303193661391256917654673579748983619101229337776995574989101525295578632981918777232038222679949264372167418981038519164359046193397794833575692294838270919137212503594644756884879905102382013616716795766055806380675079122193261937202152727372307035197702671407008933906723580158843896939160889881874945976423829414877735269690727711347872615864084627631956403177338185780100778564548976884299086453421725163428017908949325966904530291069025584097022695816511626589485257615664532774194555809017763622197728156453680059300808277471558450818004384751746190317910501772671219117514746584045928056487904112720801176609889740173288130073788687010544220250814378467249611243953690831406523455960639957029937819775398561228599467536715020954136970283137688613486109370883547218314163119613810764259334933209435078926856747403933578685724271075988136268967520808025339001863614193092075106995811355116213778057037256625729238040020810096266917394213617319914026291093309897483557317625696133298013326746629673265558468135602690674704939910172338556035967840157228859997765219241095551758253889312610691956445984657535082546460420349808372702307807697037778668585720318640246334216650054353036505301550387620089144331383076791604944171531121861009872807022569971425034887955393207445086587528972631782104261610625226982484798915695532492666822649105680868782554501246818156815043534857204078057748607289822387462529373683511672270708474273078574153649263666927268413520984191265086647728912692418609093325194826161869428270138209430215739290181617579745939639392608498596400274014103435747462262045586624613109970954762445247628187031774393639286689201449970646288560996969456145518290732375783779950601901268751888374247634804346090070762202809312421725537938059723148831745384765961875359917754708570262909323774973728101735046489385116839098154905761289565030660932858839402457684704605894701939226586411257561719440368089980555960049063794123068432799043630558103308335378100690170353973384441557259766075780510887009923794374174414344793891145106172614982174022423725641446878993111773629101974963001417653742183922637679467704643683488299451383820099923197374567580088833681469257525555566554059017269673597621231456370183587051700138951722854738823417346171701112221512801669470086625272428387110466009926633732340715338158014022960380535876415340423270463298180055 p = 1031258570212585108808698603414182767555445052897677639423866948951702189749952118077362278114791597873887374857849110608843945147999602931524514893327261593245634596300688793100804696383294331600862616307361838713625075530605923033057798420292607084313324005960030670742335903236707051347424668165182998981826362651597673529922520050741321978487995340508870176506061078988455472726629983757177891334495427992036037888916869197023625923268730362395628981698644454605598015102743149344660035753289954772524768182414961907417128262780872736150088018242362782713626021366840839008377050943258156783230469319218694881328828604655568910359478263596900470171095487577492594356082970726490010775806829047896425017646008684855593468580466231984962033813483461967968983477403906884788740883210124619436397985264796766794127947460072675613579010189440726827908362619176030945977304565494739199204024180711769355470160343449180210621099035783410130473892034907154940221812620552070078037267581459485481935234171716161857442373193231844735828719676870205773550742748115751746679863993359028942356902435101216732629439956995080906856117921874868778807816437722779021770626701787029584425435823156963642252037843217983129594166645096945256426591587 phi = pow(p - 1, 2) d = number.inverse(e, phi) ans = pow(c, d, p) print(number.long_to_bytes(ans))
elif high > mid and mid**n > x: high = mid else: return mid return mid + 1 def xgcd(a, b): """return (x, y) such that a*x + b*y = gcd(a, b)""" x0, x1, y0, y1 = 0, 1, 1, 0 while a != 0: (q, a), b = divmod(b, a), a y0, y1 = y1, y0 - q * y1 x0, x1 = x1, x0 - q * x1 return x0, y0 N = N_us * N_ger * N_rus C = 0 for c, n in ((C_us, N_us), (C_ger, N_ger), (C_rus, N_rus)): m = N // n r, s = xgcd(n, m) C += c * s * m C %= N m = root(C, 3) print(long_to_bytes(m).decode())
def decrypt(self, ct, sentinel): """Decrypt a PKCS#1 v1.5 ciphertext. This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in section 7.2.2 of RFC3447. For a complete example see `Cryptodome.Cipher.PKCS1_v1_5`. :Parameters: ct : byte string The ciphertext that contains the message to recover. sentinel : any type The object to return to indicate that an error was detected during decryption. :Return: A byte string. It is either the original message or the ``sentinel`` (in case of an error). :Raise ValueError: If the ciphertext length is incorrect :Raise TypeError: If the RSA key has no private half. :attention: You should **never** let the party who submitted the ciphertext know that this function returned the ``sentinel`` value. Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts), an attacker is able to recontruct the plaintext of any other encryption that were carried out with the same RSA public key (see `Bleichenbacher's`__ attack). In general, it should not be possible for the other party to distinguish whether processing at the server side failed because the value returned was a ``sentinel`` as opposed to a random, invalid message. In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5 embeds no good integrity check. There is roughly one chance in 2^16 for a random ciphertext to be returned as a valid message (although random looking). It is therefore advisabled to: 1. Select as ``sentinel`` a value that resembles a plausable random, invalid message. 2. Not report back an error as soon as you detect a ``sentinel`` value. Put differently, you should not explicitly check if the returned value is the ``sentinel`` or not. 3. Cover all possible errors with a single, generic error indicator. 4. Embed into the definition of ``message`` (at the protocol level) a digest (e.g. ``SHA-1``). It is recommended for it to be the rightmost part ``message``. 5. Where possible, monitor the number of errors due to ciphertexts originating from the same party, and slow down the rate of the requests from such party (or even blacklist it altogether). **If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.** .. __: http://www.bell-labs.com/user/bleichen/papers/pkcs.ps """ # See 7.2.1 in RFC3447 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes # Step 1 if len(ct) != k: raise ValueError("Ciphertext with incorrect length.") # Step 2a (O2SIP) ct_int = bytes_to_long(ct) # Step 2b (RSADP) m_int = self._key._decrypt(ct_int) # Complete step 2c (I2OSP) em = long_to_bytes(m_int, k) # Step 3 sep = em.find(bchr(0x00),2) if not em.startswith(b('\x00\x02')) or sep<10: return sentinel # Step 4 return em[sep+1:]
#!/usr/bin/env python3 from Cryptodome.Util.number import long_to_bytes from functools import reduce import gmpy c = 6266581299888401431356019685857676721005512997725159922779081961687643614552653153087574483260130787394160238006621991373227618549941265310264217473547297262515846291154704261375478737585940284506042322757388295442811794858315659558177274861105499106012394787944480624348595769062576911527554694105458355954925447902832889109094510575783610671 n = 17149550745874756611746349488171572231438371200348231719633014088974736884802848076523237745947661578970091737572169150026095175495608893630786048592718568155807514756252934154133476630756347906038049557655224302390258950256747769841607263907756157608189991803473550647948992295574885014528722284654016490409005358726716870537326555765863520721 factors_n = "8651947541 × 9022377359 × 9117056461 × 9134561857 × 9281718053 × 9418281881 × 9714592933 × 10327569731 × 11298080977 × 11699883407 × 11736985709 × 11961457069 × 12046239061 × 12163490981 × 12314578559 × 12353897999 × 12372681967 × 12737016053 × 12903583153 × 13415378663 × 13501287773 × 13982548169 × 13997803987 × 14024346211 × 14401620067 × 14416034443 × 14464157419 × 14873424353 × 15341140931 × 15357953617 × 15621353197 × 15670322663 × 16471179583 × 16950016631".split(" × ") factors_n = [int(f) for f in factors_n] # as always https://www.alpertron.com.ar/ECM.HTM phi = reduce(lambda x,y:x*(y-1),factors_n,1) e = 65537 d = gmpy.invert(e,phi) print(long_to_bytes(pow(c,d,n)).decode('utf-8'))
eaten_onion = parse_onion(out.strip().decode()[:-30]) route = "=============================================================================================================================================================================x========xxxx====xx==xxxx==xxxx==xxxxxxxxxxxxx===xxxxxxxxxxxxxxxx==xxxxxxxxxxxxx=xx" count = 0 onion2 = "" for idx, symbol in enumerate(route): if route[idx] == '=': onion2 += eaten_onion[count] count += 1 else: onion2 += '0' onion2 = bytes_to_long(bytes.fromhex(onion2)) print() print(f'coppersmith({n}, 3, {onion2}, {onion})') conn.sendline(long_to_bytes(onion2 + int(input("x = ?"))).hex()) # Level 3 conn.recvuntil('layer: ') conn.sendline('192') conn.recvuntil('your onion') out = conn.recvuntil('layer: ') onion = parse_onion(out.strip().decode()[:-6]) print(onion) conn.sendline('192') conn.recvuntil('layer: ') conn.sendline('192') conn.recvuntil('layer: ') conn.sendline('192') conn.recvuntil("How would my onion looks like?")
if len(vector) == 12: result_vector = vector.bin + "0" * 31 + "1" return bitstring_to_bytes(result_vector) else: length_vector = len(vector.bin) s = 128 * ceil(length_vector / 128) - length_vector result_vector = vector.bin + "0" * (s + 64) + bin(length_vector)[2:] return ghash(result_vector) if __name__ == '__main__': test_str = input("Введите строку:\n") res = ''.join(format(ord(i), 'b') for i in test_str) addi_auth_data = bitstring.BitArray(get_random_bytes(8)).bin lenght_aad = len(addi_auth_data) key = long_to_bytes(pow(2, 128) - 1) aes = AES.new(key, AES.MODE_EAX) H, tag = aes.encrypt_and_digest(bytearray(16)) H_int = format(int.from_bytes(H, byteorder='big'), "b").rjust(128, "0") tag_int = format(int.from_bytes(tag, byteorder='big'), "b").rjust(128, "0") init_vector = bitstring.BitArray(bytearray(16)) j0 = make_a_blockJ(init_vector) cipher_text = gctr(inc(j0, 32), res, key) if len(cipher_text) % 128 != 0: cipher_text = cipher_text.rjust( 128 - len(cipher_text) % 128 + len(cipher_text), "0") u = 128 * ceil(lenght_aad / 128) - len(cipher_text) v = 128 * ceil(lenght_aad / 128) - lenght_aad addi_auth_dat = addi_auth_data + ("0" * u) + cipher_text + ( "0" * v) + bin(lenght_aad)[2:] + bin(len(cipher_text))[2:] tag_cipher = gctr(j0, addi_auth_dat, key)
def decrypt(self, ciphertext, sentinel, expected_pt_len=0): r"""Decrypt a PKCS#1 v1.5 ciphertext. This is the function ``RSAES-PKCS1-V1_5-DECRYPT`` specified in `section 7.2.2 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-29>`_. Args: ciphertext (bytes/bytearray/memoryview): The ciphertext that contains the message to recover. sentinel (any type): The object to return whenever an error is detected. expected_pt_len (integer): The length the plaintext is known to have, or 0 if unknown. Returns (byte string): It is either the original message or the ``sentinel`` (in case of an error). .. warning:: PKCS#1 v1.5 decryption is intrinsically vulnerable to timing attacks (see `Bleichenbacher's`__ attack). **Use PKCS#1 OAEP instead**. This implementation attempts to mitigate the risk with some constant-time constructs. However, they are not sufficient by themselves: the type of protocol you implement and the way you handle errors make a big difference. Specifically, you should make it very hard for the (malicious) party that submitted the ciphertext to quickly understand if decryption succeeded or not. To this end, it is recommended that your protocol only encrypts plaintexts of fixed length (``expected_pt_len``), that ``sentinel`` is a random byte string of the same length, and that processing continues for as long as possible even if ``sentinel`` is returned (i.e. in case of incorrect decryption). .. __: https://dx.doi.org/10.1007/BFb0055716 """ # See 7.2.2 in RFC8017 k = self._key.size_in_bytes() # Step 1 if len(ciphertext) != k: raise ValueError("Ciphertext with incorrect length (not %d bytes)" % k) # Step 2a (O2SIP) ct_int = bytes_to_long(ciphertext) # Step 2b (RSADP) m_int = self._key._decrypt(ct_int) # Complete step 2c (I2OSP) em = long_to_bytes(m_int, k) # Step 3 (not constant time when the sentinel is not a byte string) output = bytes(bytearray(k)) if not is_bytes(sentinel) or len(sentinel) > k: size = _pkcs1_decode(em, b'', expected_pt_len, output) if size < 0: return sentinel else: return output[size:] # Step 3 (somewhat constant time) size = _pkcs1_decode(em, sentinel, expected_pt_len, output) return output[size:]
from Cryptodome.Util.number import bytes_to_long, long_to_bytes import random magic = -2366540547707921699196359399704685795692230503857310199630127241713302904294984638188222048954693422933286057485453364955232326575156580931098343765793 enc = 481730728147477590058623891675498051334529574592495375656331717409768416155349933803891410647003817827440361572464319442970436132820134834740943058323 for i in range(256): for j in range(256): for k in range(256): random.seed(i); b = random.getrandbits(500) random.seed(j); c = random.getrandbits(500) random.seed(k); d = random.getrandbits(500) ct = magic ^ enc ^ -1 ^ (b & c) ^ (c | d) ^ b ^ c ^ d ct = long_to_bytes(ct) try: print(ct.decode()) break except: pass
def _create_ctr_cipher(factory, **kwargs): """Instantiate a cipher object that performs CTR encryption/decryption. :Parameters: factory : module The underlying block cipher, a module from ``Cryptodome.Cipher``. :Keywords: nonce : binary string The fixed part at the beginning of the counter block - the rest is the counter number that gets increased when processing the next block. The nonce must be such that no two messages are encrypted under the same key and the same nonce. The nonce must be shorter than the block size (it can have zero length). If this parameter is not present, a random nonce will be created with length equal to half the block size. No random nonce shorter than 64 bits will be created though - you must really think through all security consequences of using such a short block size. initial_value : posive integer The initial value for the counter. If not present, the cipher will start counting from 0. The value is incremented by one for each block. The counter number is encoded in big endian mode. counter : object Instance of ``Cryptodome.Util.Counter``, which allows full customization of the counter block. This parameter is incompatible to both ``nonce`` and ``initial_value``. Any other keyword will be passed to the underlying block cipher. See the relevant documentation for details (at least ``key`` will need to be present). """ cipher_state = factory._create_base_cipher(kwargs) counter = kwargs.pop("counter", None) nonce = kwargs.pop("nonce", None) initial_value = kwargs.pop("initial_value", None) if kwargs: raise TypeError("Invalid parameters for CTR mode: %s" % str(kwargs)) if counter is not None and (nonce, initial_value) != (None, None): raise TypeError("'counter' and 'nonce'/'initial_value'" " are mutually exclusive") if counter is None: # Cryptodome.Util.Counter is not used if nonce is None: if factory.block_size < 16: raise TypeError("Impossible to create a safe nonce for short" " block sizes") nonce = get_random_bytes(factory.block_size // 2) if initial_value is None: initial_value = 0 if len(nonce) >= factory.block_size: raise ValueError("Nonce is too long") counter_len = factory.block_size - len(nonce) if (1 << (counter_len * 8)) - 1 < initial_value: raise ValueError("Initial counter value is too large") return CtrMode( cipher_state, # initial_counter_block nonce + long_to_bytes(initial_value, counter_len), len(nonce), # prefix counter_len, False) # little_endian # Cryptodome.Util.Counter is used # 'counter' used to be a callable object, but now it is # just a dictionary for backward compatibility. _counter = dict(counter) try: counter_len = _counter.pop("counter_len") prefix = _counter.pop("prefix") suffix = _counter.pop("suffix") initial_value = _counter.pop("initial_value") little_endian = _counter.pop("little_endian") except KeyError: raise TypeError("Incorrect counter object" " (use Cryptodome.Util.Counter.new)") # Compute initial counter block words = [] while initial_value > 0: words.append(bchr(initial_value & 255)) initial_value >>= 8 words += [bchr(0)] * max(0, counter_len - len(words)) if not little_endian: words.reverse() initial_counter_block = prefix + b("").join(words) + suffix if len(initial_counter_block) != factory.block_size: raise ValueError("Size of the counter block (% bytes) must match" " block size (%d)" % (len(initial_counter_block), factory.block_size)) return CtrMode(cipher_state, initial_counter_block, len(prefix), counter_len, little_endian)
def decrypt(self, ciphertext, sentinel): """Decrypt a PKCS#1 v1.5 ciphertext. This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in `section 7.2.2 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-29>`_. :param ciphertext: The ciphertext that contains the message to recover. :type ciphertext: byte string :param sentinel: The object to return whenever an error is detected. :type sentinel: any type :Returns: A byte string. It is either the original message or the ``sentinel`` (in case of an error). :Raises ValueError: If the ciphertext length is incorrect :Raises TypeError: If the RSA key has no private half (i.e. it cannot be used for decyption). .. warning:: You should **never** let the party who submitted the ciphertext know that this function returned the ``sentinel`` value. Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts), an attacker is able to recontruct the plaintext of any other encryption that were carried out with the same RSA public key (see `Bleichenbacher's`__ attack). In general, it should not be possible for the other party to distinguish whether processing at the server side failed because the value returned was a ``sentinel`` as opposed to a random, invalid message. In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5 embeds no good integrity check. There is roughly one chance in 2\ :sup:`16` for a random ciphertext to be returned as a valid message (although random looking). It is therefore advisabled to: 1. Select as ``sentinel`` a value that resembles a plausable random, invalid message. 2. Not report back an error as soon as you detect a ``sentinel`` value. Put differently, you should not explicitly check if the returned value is the ``sentinel`` or not. 3. Cover all possible errors with a single, generic error indicator. 4. Embed into the definition of ``message`` (at the protocol level) a digest (e.g. ``SHA-1``). It is recommended for it to be the rightmost part ``message``. 5. Where possible, monitor the number of errors due to ciphertexts originating from the same party, and slow down the rate of the requests from such party (or even blacklist it altogether). **If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.** .. __: http://www.bell-labs.com/user/bleichen/papers/pkcs.ps """ # See 7.2.1 in RFC3447 modBits = Cryptodome.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes # Step 1 if len(ciphertext) != k: raise ValueError("Ciphertext with incorrect length.") # Step 2a (O2SIP) ct_int = bytes_to_long(ciphertext) # Step 2b (RSADP) m_int = self._key._decrypt(ct_int) # Complete step 2c (I2OSP) em = long_to_bytes(m_int, k) # Step 3 sep = em.find(bchr(0x00), 2) if not em.startswith(b('\x00\x02')) or sep < 10: return sentinel # Step 4 return em[sep + 1:]
def __init__(self, factory, key, nonce, mac_len, cipher_params, ghash_c): self.block_size = factory.block_size if self.block_size != 16: raise ValueError("GCM mode is only available for ciphers" " that operate on 128 bits blocks") if len(nonce) == 0: raise ValueError("Nonce cannot be empty") if isinstance(nonce, str): raise TypeError("Nonce must be a byte string") # See NIST SP 800 38D, 5.2.1.1 if len(nonce) > 2**64 - 1: raise ValueError("Nonce exceeds maximum length") self.nonce = _copy_bytes(None, None, nonce) """Nonce""" self._factory = factory self._key = _copy_bytes(None, None, key) self._tag = None # Cache for MAC tag self._mac_len = mac_len if not (4 <= mac_len <= 16): raise ValueError("Parameter 'mac_len' must be in the range 4..16") # Allowed transitions after initialization self._next = [self.update, self.encrypt, self.decrypt, self.digest, self.verify] self._no_more_assoc_data = False # Length of associated data self._auth_len = 0 # Length of the ciphertext or plaintext self._msg_len = 0 # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H # See also Algorithm 5 (decryption) hash_subkey = factory.new(key, self._factory.MODE_ECB, **cipher_params ).encrypt(b'\x00' * 16) # Step 2 - Compute J0 (integer, not byte string!) if len(self.nonce) == 12: self._j0 = bytes_to_long(self.nonce + b"\x00\x00\x00\x01") else: fill = (16 - (len(nonce) % 16)) % 16 + 8 ghash_in = (self.nonce + b'\x00' * fill + long_to_bytes(8 * len(nonce), 8)) self._j0 = bytes_to_long(_GHASH(hash_subkey, ghash_c) .update(ghash_in) .digest()) # Step 3 - Prepare GCTR cipher for encryption/decryption nonce_ctr = long_to_bytes(self._j0 >> 32, 12) iv_ctr = (self._j0 + 1) & 0xFFFFFFFF self._cipher = factory.new(key, self._factory.MODE_CTR, initial_value=iv_ctr, nonce=nonce_ctr, **cipher_params) # Step 5 - Bootstrat GHASH self._signer = _GHASH(hash_subkey, ghash_c) # Step 6 - Prepare GCTR cipher for GMAC self._tag_cipher = factory.new(key, self._factory.MODE_CTR, initial_value=self._j0, nonce=b"", **cipher_params) # Cache for data to authenticate self._cache = b"" self._status = MacStatus.PROCESSING_AUTH_DATA
def __init__(self, randomness): length = len(randomness) self._idx = 0 # Fix required to get the right K (see how randint() works!) self._randomness = long_to_bytes(bytes_to_long(randomness) - 1, length)
def _create_ctr_cipher(factory, **kwargs): """Instantiate a cipher object that performs CTR encryption/decryption. :Parameters: factory : module The underlying block cipher, a module from ``Cryptodome.Cipher``. :Keywords: nonce : bytes/bytearray/memoryview The fixed part at the beginning of the counter block - the rest is the counter number that gets increased when processing the next block. The nonce must be such that no two messages are encrypted under the same key and the same nonce. The nonce must be shorter than the block size (it can have zero length; the counter is then as long as the block). If this parameter is not present, a random nonce will be created with length equal to half the block size. No random nonce shorter than 64 bits will be created though - you must really think through all security consequences of using such a short block size. initial_value : posive integer or bytes/bytearray/memoryview The initial value for the counter. If not present, the cipher will start counting from 0. The value is incremented by one for each block. The counter number is encoded in big endian mode. counter : object Instance of ``Cryptodome.Util.Counter``, which allows full customization of the counter block. This parameter is incompatible to both ``nonce`` and ``initial_value``. Any other keyword will be passed to the underlying block cipher. See the relevant documentation for details (at least ``key`` will need to be present). """ cipher_state = factory._create_base_cipher(kwargs) counter = kwargs.pop("counter", None) nonce = kwargs.pop("nonce", None) initial_value = kwargs.pop("initial_value", None) if kwargs: raise TypeError("Invalid parameters for CTR mode: %s" % str(kwargs)) if counter is not None and (nonce, initial_value) != (None, None): raise TypeError("'counter' and 'nonce'/'initial_value'" " are mutually exclusive") if counter is None: # Cryptodome.Util.Counter is not used if nonce is None: if factory.block_size < 16: raise TypeError("Impossible to create a safe nonce for short" " block sizes") nonce = get_random_bytes(factory.block_size // 2) else: if len(nonce) >= factory.block_size: raise ValueError("Nonce is too long") # What is not nonce is counter counter_len = factory.block_size - len(nonce) if initial_value is None: initial_value = 0 if isinstance(initial_value, (int, long)): if (1 << (counter_len * 8)) - 1 < initial_value: raise ValueError("Initial counter value is too large") initial_counter_block = nonce + long_to_bytes(initial_value, counter_len) else: if len(initial_value) != counter_len: raise ValueError("Incorrect length for counter byte string (%d bytes, expected %d)" % (len(initial_value), counter_len)) initial_counter_block = nonce + initial_value return CtrMode(cipher_state, initial_counter_block, len(nonce), # prefix counter_len, False) # little_endian # Cryptodome.Util.Counter is used # 'counter' used to be a callable object, but now it is # just a dictionary for backward compatibility. _counter = dict(counter) try: counter_len = _counter.pop("counter_len") prefix = _counter.pop("prefix") suffix = _counter.pop("suffix") initial_value = _counter.pop("initial_value") little_endian = _counter.pop("little_endian") except KeyError: raise TypeError("Incorrect counter object" " (use Cryptodome.Util.Counter.new)") # Compute initial counter block words = [] while initial_value > 0: words.append(struct.pack('B', initial_value & 255)) initial_value >>= 8 words += [ b'\x00' ] * max(0, counter_len - len(words)) if not little_endian: words.reverse() initial_counter_block = prefix + b"".join(words) + suffix if len(initial_counter_block) != factory.block_size: raise ValueError("Size of the counter block (%d bytes) must match" " block size (%d)" % (len(initial_counter_block), factory.block_size)) return CtrMode(cipher_state, initial_counter_block, len(prefix), counter_len, little_endian)
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 : byte string The ciphertext that contains the message to recover. :Return: A byte 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. """ # See 7.1.2 in RFC3447 modBits = Cryptodome.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) ct_int = bytes_to_long(ct) # 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:]