Beispiel #1
0
 def dh2(self):
     """ Executes the second half of the Diffie-Hellman key exchange """
     self.write_serial_string(str(Opcodes.ECDH_SHAKE))
     pub_arduino = int(self.read_serial_raw(),
                       base=16).to_bytes(32, byteorder="big")
     self.write_serial(self.keys["public"])
     self.symm_key = curve.calculateAgreement(self.keys["private"],
                                              pub_arduino)[:16]
Beispiel #2
0
    def calculateAgreement(publicKey, privateKey):
        """
        :type publicKey: ECPublicKey
        :type privateKey: ECPrivateKey
        """
        if publicKey.getType() != privateKey.getType():
            raise InvalidKeyException("Public and private keys must be of the same type!")

        if publicKey.getType() == Curve.DJB_TYPE:
            return _curve.calculateAgreement(privateKey.getPrivateKey(), publicKey.getPublicKey())
        else:
            raise InvalidKeyException("Unknown type: %s" % publicKey.getType())
Beispiel #3
0
 def calculateAgreement(self, private_key, public_key):
     return axolotl_curve25519.calculateAgreement(private_key, public_key)
Beispiel #4
0
 def generateSharedSecret(self, public_key):
     private_key = self.Curve.private_key
     shared_secret = axolotl_curve25519.calculateAgreement(
         private_key, public_key)
     return shared_secret
Beispiel #5
0
def generate_shared_secret(private_key, public_key):
    shared_secret = curve.calculateAgreement(private_key, public_key)
    # shared_secret = Box(private_key, public_key).shared_key()

    return shared_secret
    def extract_validated_payload(self, msg):
        try:
            if not msg['payload'].startswith("SIG/2"):
                return super().extract_validated_payload(msg)

            beat = int(self.beat())
            try:
                hdr, b64sig, payload = msg['payload'].split(' ', 2)
                sig = base64.b64decode(b64sig)

                msg['hdr'] = hdr
                msg['sig'] = sig
                msg['payload'] = payload

                signed_payload = msg['payload']

                if not super().extract_validated_payload(msg):
                    return None

                clean_payload = msg['payload']

                cmd = msg['payload'].split(" ")[0]
            except Exception as e:
                self.logger.warning(
                    "Could not parse curve25519 signature from payload '{}' -- ignored {}"
                    .format(msg['payload'], str(e)))
                return None

            if len(sig) != 64:
                self.logger.error(
                    "Signature wrong length for '{}' - ignored".format(
                        msg['node']))
                return None

            # Process TOFU information if we do not (yet) know the public key
            # without validating the signature.
            #
            seskey = None
            if cmd == 'announce' or cmd == 'welcome':
                try:
                    cmd, ip, pubkey, seskey = clean_payload.split(" ")

                except Exception as e:
                    self.logger.error("Error parsing announce. Ignored. " +
                                      str(e))
                    return None

                publickey = base64.b64decode(pubkey)
                if len(publickey) != 32:
                    self.logger.error(
                        "Ignoring malformed signing public key of node {}".
                        format(msg['node']))
                    return None

                publickey = ed25519.VerifyingKey(pubkey, encoding="base64")

                seskey = base64.b64decode(seskey)
                if len(seskey) != 32:
                    self.logger.error(
                        "Ignoring malformed session public key of node {}".
                        format(msg['node']))
                    return None

                if msg['node'] in self.pubkeys:
                    if self.pubkeys[msg['node']] != publickey:
                        self.logger.info(
                            "Ignoring (changed) public key of node {}".format(
                                msg['node']))
                        return None
                else:
                    self.logger.debug(
                        "Potentially learned a public key of node {} on first contact - checking signature next."
                        .format(msg['node']))
            else:
                if not msg['node'] in self.pubkeys:
                    self.logger.info(
                        "No public key for node {} -- ignoring.".format(
                            msg['node']))
                    return None
                publickey = self.pubkeys[msg['node']]

            if not self.cnf.privatekey:
                return None

            # Note: this is the payload `as of now' -- not the further decoded/stripped of its beat payload.
            # Because we also (want to) have the signature cover the beat - to prevent replay.
            # Todo: consider a nonce.
            try:
                publickey.verify(b64sig,
                                 signed_payload.encode('ASCII'),
                                 encoding="base64")
                self.logger.debug("Good signature on " + signed_payload)
            except ed25519.BadSignatureError:
                self.logger.warning("Bad signature for {} - ignored".format(
                    msg['node']))
                return None
            except Exception as e:
                self.logger.warning(
                    "Invalid signature for {}: {} -- ignored.".format(
                        msg['node'], str(e)))
                return None

            if not msg['node'] in self.pubkeys:
                self.pubkeys[msg['node']] = publickey
                self.logger.info(
                    "Learned a public key of node {} on first contact.".format(
                        msg['node']))

            if (cmd == 'announce' or cmd == 'welcome') and seskey:
                session_key = curve.calculateAgreement(self.session_priv,
                                                       seskey)
                self.sharedkey[msg['node']] = hashlib.sha256(
                    session_key).digest()

                self.logger.debug(
                    "(Re)calculated shared secret with node {}.".format(
                        msg['node']))

            msg['validated'] = 20

        except Exception as e:
            if 1:
                exc_type, exc_obj, tb = sys.exc_info()
                f = tb.tb_frame
                lineno = tb.tb_lineno
                filename = f.f_code.co_filename
                linecache.checkcache(filename)
                line = linecache.getline(filename, lineno, f.f_globals)
                self.logger.debug('EXCEPTION IN ({}, LINE {} "{}"): {}'.format(
                    filename, lineno, line.strip(), exc_obj))
        return msg
Beispiel #7
0
        print(f"[HUMAN_VERIFICATION_REQUIRED]")
        hv = HumanVerif(verify['error']['metadata'][11][1],
                        verify['error']['metadata'][11][2])
        RetryReq(session, hv)

cl.validateProfile(session, 'yinmo')

exchangeEncryptionKey = cl.exchangeEncryptionKey(session,
                                                 b64_public_key.decode(),
                                                 b64_nonce.decode(), 1)
print(f'exchangeEncryptionKey: {exchangeEncryptionKey}')

exc_key = base64.b64decode(exchangeEncryptionKey[1])
exc_nonce = base64.b64decode(exchangeEncryptionKey[2])

sign = Curve25519.calculateAgreement(private_key, exc_key)
print(f"sign: {sign}")

password = '******'

master_key = getSHA256Sum(b'master_key', sign, nonce, exc_nonce)
aes_key = getSHA256Sum(b'aes_key', master_key)
hmac_key = getSHA256Sum(b'hmac_key', master_key)

e1 = AES.new(aes_key[:16], AES.MODE_CBC, aes_key[16:32])
doFinal = e1.encrypt(pad(password.encode(), 16))
hmacd = hmac.new(hmac_key, msg=doFinal, digestmod=hashlib.sha256).digest()
encPwd = base64.b64encode(doFinal + hmacd).decode()

setPwd = cl.setPassword(session, encPwd, 1)
print(setPwd)
  def extract_validated_payload(self, msg):
   try:
    if not msg['payload'].startswith("SIG/2"):
        return super().extract_validated_payload(msg)

    beat = int(self.beat())
    try:
        hdr, b64sig, payload = msg['payload'].split(' ',2)
        sig = base64.b64decode(b64sig)
        
        msg['hdr'] = hdr
        msg['sig'] = sig
        msg['payload'] = payload

        signed_payload = msg['payload']
        
        if not super().extract_validated_payload(msg):
           return None
        
        clean_payload = msg['payload']

        cmd = msg['payload'].split(" ")[0]
    except Exception as e:
        self.logger.warning("Could not parse curve25519 signature from payload '{}' -- ignored {}".format(msg['payload'],str(e)))
        return None

    if len(sig) != 64:
       self.logger.error("Signature wrong length for '{}' - ignored".format(msg['node']))
       return None

    # Process TOFU information if we do not (yet) know the public key
    # without validating the signature.
    #
    seskey = None
    nonce = None
    if cmd == 'announce' or cmd == 'welcome':
            try:
                # if cmd == 'welcome':
                    cmd, ip, pubkey, seskey, nonce  = clean_payload.split(" ")
                #else:
                #    cmd, ip, pubkey, seskey = clean_payload.split(" ")

            except Exception as e:
                self.logger.error("Error parsing announce. Ignored. "+str(e))
                return None

            publickey = base64.b64decode(pubkey)
            if len(publickey) != 32:
                    self.logger.error("Ignoring malformed signing public key of node {}".format(msg['node']))
                    return None

            if publickey == self.cnf.publickey.to_bytes():
                    self.logger.debug("Ignoring the message - as it is my own (pubkey).")

            publickey = ed25519.VerifyingKey(pubkey, encoding="base64")
            
            seskey = base64.b64decode(seskey)
            if len(seskey) != 32:
                    self.logger.error("Ignoring malformed session public key of node {}".format(msg['node']))
                    return None

            if msg['client'] == self.cnf.node:
                    self.logger.debug("Ignoring the message - as it is my own (name).")

            if msg['node'] in self.pubkeys:
                if self.pubkeys[msg['node']] != publickey:
                   self.logger.critical("Ignoring (changed) public key of node {}".format(msg['node']))
                   return None
            else:
                 self.logger.debug("Potentially learned a public key of node {} on first contact - checking signature next.".format(msg['node']))
    else:
        if not msg['node'] in self.pubkeys:
            self.logger.info("No public key for node {} -- ignoring.".format(msg['node']))
            return None
        publickey = self.pubkeys[ msg['node'] ]
    
    if not self.cnf.privatekey:
        return None

    # Note: this is the payload `as of now' -- not the further decoded/stripped of its beat payload.
    # Because we also (want to) have the signature cover the beat - to prevent replay.
    # Todo: consider a nonce.
    try:
        publickey.verify(b64sig, signed_payload.encode('ASCII'), encoding="base64")
        self.logger.debug("Good signature on " + signed_payload)
    except ed25519.BadSignatureError:
        self.logger.warning("Bad signature for {} - ignored".format(msg['node']))
        return None
    except Exception as e:
        self.logger.warning("Invalid signature for {}: {} -- ignored.".format(msg['node'], str(e)))
        return None

    if not msg['node'] in self.pubkeys:
        self.pubkeys[ msg['node'] ] = publickey
        self.save_pkdb()  
        self.logger.info("Learned a public key of node {} on first contact.".format(msg['node']))
    else:
        if (self.pubkeys[ msg['node'] ] == publickey):
        	self.logger.debug("Already have this very public key recorded for this node {}.".format(msg['node']))
        else:
        	self.logger.warning("Does NOT match the key recorded for node {}.".format(msg['node']))

    if (cmd == 'announce' or cmd == 'welcome'):
        if (seskey): 
            session_key = curve.calculateAgreement(self.session_priv, seskey)
            self.sharedkey[ msg['node'] ] = hashlib.sha256(session_key).digest()
            if (nonce):
                    self.send_tofu('welcome', msg['node'], nonce)

        self.logger.debug("(Re)calculated shared secret with node {}.".format(msg['node']))

    msg['validated'] = 20
  
   except Exception as e:
        if 1:
            exc_type, exc_obj, tb = sys.exc_info()
            f = tb.tb_frame
            lineno = tb.tb_lineno
            filename = f.f_code.co_filename
            linecache.checkcache(filename)
            line = linecache.getline(filename, lineno, f.f_globals)
            self.logger.debug('EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj))
   return msg
# Key Features -
# if backup key = type + 128
# if signature key = type + 64
# if decryption key = type + 32
# if authentication key = type + 16
# For this example it will be a decryption key
time.sleep(1.5)
print(ok.read_string())

time.sleep(2)
print('You should see your OnlyKey blink 3 times')
print()

message = 'Secret Message'
counter = b"\x00\x00\x00\x01"
shared_secret = curve.calculateAgreement(alice_private_key, bob_public_key)
h = hashlib.sha256()
h.update(counter)
h.update(shared_secret)
h.update(message.encode())
d = h.digest()
KEK = d

payload = alice_public_key

#We are simulating message here, according to refernce below it is a known value to both parties - unsigned char message[256];

#
#    // Reference - https://www.ietf.org/mail-archive/web/openpgp/current/msg00637.html
#	// https://fossies.org/linux/misc/gnupg-2.1.17.tar.gz/gnupg-2.1.17/g10/ecdh.c
#	// gcry_md_write(h, "\x00\x00\x00\x01", 4);      /* counter = 1 */
Beispiel #10
0
 def generateSharedSecret(self, private_key, public_key):
     return Curve25519.calculateAgreement(bytes(private_key), bytes(public_key))