示例#1
0
文件: dh.py 项目: 306235911/IpPool
 def public_numbers(self):
     p = self._backend._ffi.new("BIGNUM **")
     g = self._backend._ffi.new("BIGNUM **")
     self._backend._lib.DH_get0_pqg(self._dh_cdata,
                                    p, self._backend._ffi.NULL, g)
     self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
     self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
     pub_key = self._backend._ffi.new("BIGNUM **")
     self._backend._lib.DH_get0_key(self._dh_cdata,
                                    pub_key, self._backend._ffi.NULL)
     self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
     return dh.DHPublicNumbers(
         parameter_numbers=dh.DHParameterNumbers(
             p=self._backend._bn_to_int(p[0]),
             g=self._backend._bn_to_int(g[0])
         ),
         y=self._backend._bn_to_int(pub_key[0])
     )
示例#2
0
    def post_dissection(self, m):
        """
        First we update the client DHParams. Then, we try to update the server
        DHParams generated during Server*DHParams building, with the shared
        secret. Finally, we derive the session keys and update the context.
        """
        s = self.tls_session

        if s.client_kx_ffdh_params:
            y = pkcs_os2ip(self.dh_Yc)
            param_numbers = s.client_kx_ffdh_params.parameter_numbers()
            public_numbers = dh.DHPublicNumbers(y, param_numbers)
            s.client_kx_pubkey = public_numbers.public_key(default_backend())

        if s.server_kx_privkey and s.client_kx_pubkey:
            ZZ = s.server_kx_privkey.exchange(s.client_kx_pubkey)
            s.pre_master_secret = ZZ
            s.compute_ms_and_derive_keys()
示例#3
0
 def test_dh_serialization_with_q_unsupported(self, backend, vector):
     parameters = dh.DHParameterNumbers(int(vector["p"], 16),
                                        int(vector["g"], 16),
                                        int(vector["q"], 16))
     public = dh.DHPublicNumbers(int(vector["ystatcavs"], 16), parameters)
     private = dh.DHPrivateNumbers(int(vector["xstatcavs"], 16), public)
     private_key = private.private_key(backend)
     public_key = private_key.public_key()
     with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
         private_key.private_bytes(serialization.Encoding.PEM,
                                   serialization.PrivateFormat.PKCS8,
                                   serialization.NoEncryption())
     with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
         public_key.public_bytes(
             serialization.Encoding.PEM,
             serialization.PublicFormat.SubjectPublicKeyInfo)
     with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
         parameters.parameters(backend).parameter_bytes(
             serialization.Encoding.PEM,
             serialization.ParameterFormat.PKCS3)
示例#4
0
    def test_convert_to_numbers(self, backend):
        parameters = backend.generate_dh_private_key_and_parameters(2, 512)

        private = parameters.private_numbers()

        p = private.public_numbers.parameter_numbers.p
        g = private.public_numbers.parameter_numbers.g

        params = dh.DHParameterNumbers(p, g)
        public = dh.DHPublicNumbers(1, params)
        private = dh.DHPrivateNumbers(2, public)

        deserialized_params = params.parameters(backend)
        deserialized_public = public.public_key(backend)
        deserialized_private = private.private_key(backend)

        assert isinstance(deserialized_params,
                          dh.DHParametersWithSerialization)
        assert isinstance(deserialized_public, dh.DHPublicKeyWithSerialization)
        assert isinstance(deserialized_private,
                          dh.DHPrivateKeyWithSerialization)
示例#5
0
 def register_pubkey(self):
     if self.group in _tls_named_ffdh_groups:
         params = _ffdh_groups[_tls_named_ffdh_groups[self.group]][0]
         pn = params.parameter_numbers()
         public_numbers = dh.DHPublicNumbers(self.key_exchange, pn)
         self.pubkey = public_numbers.public_key(default_backend())
     elif self.group in _tls_named_curves:
         if _tls_named_curves[self.group] == "x25519":
             if conf.crypto_valid_advanced:
                 import_point = x25519.X25519PublicKey.from_public_bytes
                 self.pubkey = import_point(self.key_exchange)
         elif _tls_named_curves[self.group] != "x448":
             curve = ec._CURVE_TYPES[_tls_named_curves[self.group]]()
             try:  # cryptography >= 2.5
                 import_point = ec.EllipticCurvePublicKey.from_encoded_point  # noqa: E501
                 self.pubkey = import_point(curve, self.key_exchange)
             except AttributeError:
                 import_point = ec.EllipticCurvePublicNumbers.from_encoded_point  # noqa: E501
                 pub_num = import_point(
                     curve,
                     self.key_exchange).public_numbers()  # noqa: E501
                 self.pubkey = pub_num.public_key(default_backend())
示例#6
0
文件: dh.py 项目: mymatrix2002/XX-Net
 def public_numbers(self) -> dh.DHPublicNumbers:
     p = self._backend._ffi.new("BIGNUM **")
     g = self._backend._ffi.new("BIGNUM **")
     q = self._backend._ffi.new("BIGNUM **")
     self._backend._lib.DH_get0_pqg(self._dh_cdata, p, q, g)
     self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
     self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
     if q[0] == self._backend._ffi.NULL:
         q_val = None
     else:
         q_val = self._backend._bn_to_int(q[0])
     pub_key = self._backend._ffi.new("BIGNUM **")
     self._backend._lib.DH_get0_key(self._dh_cdata, pub_key,
                                    self._backend._ffi.NULL)
     self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
     return dh.DHPublicNumbers(
         parameter_numbers=dh.DHParameterNumbers(
             p=self._backend._bn_to_int(p[0]),
             g=self._backend._bn_to_int(g[0]),
             q=q_val,
         ),
         y=self._backend._bn_to_int(pub_key[0]),
     )
示例#7
0
 def test_symmetric_key_padding(self, backend):
     """
     This test has specific parameters that produce a symmetric key
     In length 63 bytes instead 64. We make sure here that we add
     padding to the key.
     """
     p = int("11859949538425015739337467917303613431031019140213666"
             "129025407300654026585086345323066284800963463204246390"
             "256567934582260424238844463330887962689642467123")
     g = 2
     y = int("32155788395534640648739966373159697798396966919821525"
             "72238852825117261342483718574508213761865276905503199"
             "969908098203345481366464874759377454476688391248")
     x = int("409364065449673443397833358558926598469347813468816037"
             "268451847116982490733450463194921405069999008617231539"
             "7147035896687401350877308899732826446337707128")
     parameters = dh.DHParameterNumbers(p, g)
     public = dh.DHPublicNumbers(y, parameters)
     private = dh.DHPrivateNumbers(x, public)
     key = private.private_key(backend)
     symkey = key.exchange(public.public_key(backend))
     assert len(symkey) == 512 // 8
     assert symkey[:1] == b"\x00"
示例#8
0
def create_dh_public_key(public_key_num: int):
    pn = dh.DHParameterNumbers(p, g)
    public_numbers = dh.DHPublicNumbers(public_key_num, pn)
    public_key = public_numbers.public_key(default_backend())

    return public_key
示例#9
0
 def decomposePeerKey(self,pubBobKey,pn): # Through Alice's public key creates object that allows you to compute the shared key
     peer_public_numbers = dh.DHPublicNumbers(pubBobKey, pn)
     peer_public_keyBob = peer_public_numbers.public_key(default_backend())
     return peer_public_keyBob
from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.utils import int_from_bytes

backend = default_backend()

p = int("11859949538425015739337467917303613431031019140213666"
        "12902540730065402658508634532306628480096346320424639"
        "0256567934582260424238844463330887962689642467123")

g = 2

y = int("32155788395534640648739966373159697798396966919821525"
        "72238852825117261342483718574508213761865276905503199"
        "969908098203345481366464874759377454476688391248")

x = int("409364065449673443397833358558926598469347813468816037"
        "268451847116982490733450463194921405069999008617231539"
        "7147035896687401350877308899732826446337707128")

params = dh.DHParameterNumbers(p, g)
public = dh.DHPublicNumbers(y, params)
private = dh.DHPrivateNumbers(x, public)

key = private.private_key(backend)
shared_key = key.exchange(public.public_key(backend))

# check shared key
shared_key = int_from_bytes(shared_key, 'big')
shared_key_manual = pow(y, x, p)  # y^x mod p

assert shared_key == shared_key_manual
示例#11
0
    def process(self, msg):
        """ Processa uma mensagem (`bytestring`) enviada pelo CLIENTE.
            Retorna a mensagem a transmitir como resposta (`None` para
            finalizar ligação) """
        self.msg_cnt += 1
        if (msg[:1] == b'P'):

            P = 99494096650139337106186933977618513974146274831566768179581759037259788798151499814653951492724365471316253651463342255785311748602922458795201382445323499931625451272600173180136123245441204133515800495917242011863558721723303661523372572477211620144038809673692512025566673746993593384600667047373692203583
            G = 44157404837960328768872680677686802650999163226766694797650810379076416463147265401084491113667624054557335394761604876882446924929840681990106974314935015501571333024773172440352475358750668213444607353872754650805031912866692119819377041901642732455911509867728218394542745330014071040326856846990119719675
            global pn
            global private_key
            global derived_key
            pn = dh.DHParameterNumbers(P, G)
            parameters = pn.parameters(default_backend())
            #chave privada do server
            #parameters = dh.generate_parameters(generator=2, key_size=2048, backend=default_backend())
            private_key = parameters.generate_private_key()
            #gerar chave publica

            public_key = private_key.public_key()
            public_key_server = public_key.public_numbers().y
            res = 'P' + str(G) + str(P) + str(public_key_server)
            ress = res.encode()
            msg = ress
            return msg

        elif (msg[:1] == b'S'):
            public_key_cliente = int(msg[1:].decode())
            #CALCULAR exchange
            peerPublicNumbers = dh.DHPublicNumbers(public_key_cliente, pn)
            peer_key = peerPublicNumbers.public_key(default_backend())
            shared_key = private_key.exchange(peer_key)
            # Perform key derivation.
            derived_key = HKDF(algorithm=hashes.SHA512(),
                               length=24,
                               salt=None,
                               info=b'handshake data',
                               backend=default_backend()).derive(shared_key)
            msg2s = '1'
            msg2 = str(msg2s).encode()
            return msg2

        elif (msg[:1] == b'C'):
            iv_cl = msg[1:17]
            mac_cli = msg[17:49]
            texto = msg[49:]

            cipher = Cipher(algorithms.AES(derived_key),
                            modes.CTR(iv_cl),
                            backend=backend)
            decryptor = cipher.decryptor()
            txt = decryptor.update(texto)
            #print("txt")
            #print(txt)
            #txt=txt.decode()

            #h=hmac.HMAC(key,hashes.SHA256(),backend=default_backend())
            #h.update(texto)
            #h.copy().verify(mac_cli)
            print('%d : %r' % (self.id, txt))
            #if(h.copy().verify(mac_cli)):
            #    print("mensagem recebida correta")
            #    print('Recebi (%d): %r' % (self.msg_cnt , msg))
            #else:
            #    printf("mensagem recebida está errada")
            #    print('%d : %r' % (self.id,t))

            #new = txt.upper().encode()

            iv_s = os.urandom(16)
            cipher = Cipher(algorithms.AES(derived_key),
                            modes.CTR(iv_s),
                            backend=backend)
            encryptor = cipher.encryptor()
            ct = encryptor.update(txt) + encryptor.finalize()
            ####################################
            #HMAC
            h = hmac.HMAC(key_mac, hashes.SHA256(), backend=default_backend())
            h.update(ct)
            mac_serv = h.finalize()
            carater = b'2'
            new_msg = carater + iv_s + mac_serv + ct
            ########################
            return new_msg if len(new_msg) > 0 else None
示例#12
0
def df_public_from_bytes(public_bytes):
    y = int.from_bytes(public_bytes, byteorder='big')
    peer_public_numbers = dh.DHPublicNumbers(
        y, _DH_PARAMETERS.parameter_numbers())
    return peer_public_numbers.public_key(default_backend())
示例#13
0
def on_message(client, userdata, msg):
    global name
    global mode
    global asymmetric_mode
    global symmetric_mode
    global b_public_key
    global b_public_key_ecdh
    global a_shared_key
    global f_key
    global a_key
    global h
    global hmac_key
    print(msg.topic + " -> " + str(msg.payload.decode()))

    # Connection message
    if (msg.topic == "connection"):
        print("Connection message.")

        # Initialize some variables
        name = str(msg.payload.decode()).split(":")[0]
        mode = str(msg.payload.decode()).split(":")[1]
        asymmetric_mode = int(str(msg.payload.decode()).split(":")[2])
        symmetric_mode = int(str(msg.payload.decode()).split(":")[3])

        # Save the variables for each device
        names.append(name)
        modes.append(mode)
        asymmetric_modes.append(asymmetric_mode)
        symmetric_modes.append(symmetric_mode)

        # Key exchange
        if (asymmetric_mode == 0):
            client.publish(name + "/to", "param:" + str(params_pem, 'ascii'))
            client.publish(name + "/to",
                           "public:" + str(a_public_key.public_numbers().y))
        else:
            client.publish(
                name + "/to", "public:" + a_public_key_ecdh.public_bytes(
                    encoding=Encoding.PEM,
                    format=PublicFormat.SubjectPublicKeyInfo).decode())
        client.subscribe(name + "/from")
        print("Public key sent to device.")

        # Show the information on web page
        data = {
            "type": "conexion_dispositivo",
            "payload": msg.payload.decode()
        }
        server.send_message_to_all(json.dumps(data))

    # Message from a device that has already connected
    else:

        # Topic = <Device name>/from
        name = str(msg.topic).split("/")[0]
        if (msg.topic == (name + "/from")):

            # Receive device public key
            if (str(msg.payload.decode()).split(":")[0] == "public"):

                # If we know its old public key, we upload it
                try:
                    public_keys.pop(names.index(name))
                    shared_keys.pop(names.index(name))
                    fernet_keys.pop(names.index(name))
                    aead_keys.pop(names.index(name))
                    print("Public key uploaded from device.")

                # If we don't know its public key, we save it
                except IndexError:
                    # If the device has 'output' or nothing
                    if (int(mode) > 0):
                        # HMAC key will be introduced on web page
                        data = {"type": "hmac", "name": name, "mode": mode}

                    # If the device has just 'input'
                    else:
                        # HMAC key will be introduced on device
                        hmac_key = str(os.urandom(2).hex())
                        data = {
                            "type": "hmac",
                            "name": name,
                            "mode": mode,
                            "hmac_key": hmac_key
                        }

                    # Show the correspondent information on web page
                    server.send_message_to_all(json.dumps(data))

                    print("New public key from device.")

                # DH key exchange
                if (asymmetric_modes[names.index(name)] == 0):
                    b_public_key_number = int(
                        str(msg.payload.decode()).split(":")[1])
                    peer_public_numbers = dh.DHPublicNumbers(
                        b_public_key_number, parameters.parameter_numbers())
                    b_public_key = peer_public_numbers.public_key(
                        default_backend())
                    public_keys.insert(names.index(name), b_public_key)
                    a_shared_key = a_private_key.exchange(b_public_key)

                # ECDH key exchange
                else:
                    b_public_key_number = str(
                        msg.payload.decode()).split(":")[1]
                    b_public_key_ecdh = load_pem_public_key(
                        b_public_key_number.encode())
                    a_shared_key = a_private_key_ecdh.exchange(
                        ec.ECDH(), b_public_key_ecdh)

                print("Shared key calculated.")
                # Save the shared key
                shared_keys.insert(names.index(name), a_shared_key)

                # We fix the shared key for Fernet using HASH and save it
                derived_key_fernet = HKDF(
                    algorithm=hashes.SHA256(),
                    length=32,
                    salt=None,
                    info=b'handshake data').derive(a_shared_key)
                key_fernet = base64.urlsafe_b64encode(derived_key_fernet)
                f_key = Fernet(key_fernet)
                fernet_keys.insert(names.index(name), f_key)

                # We fix the shared key for AEAD using HASH and save it
                derived_key_aead = HKDF(
                    algorithm=hashes.SHA256(),
                    length=24,
                    salt=None,
                    info=b'handshake data').derive(a_shared_key)
                key_aead = base64.urlsafe_b64encode(derived_key_aead)
                a_key = aead.AESGCM(key_aead)
                aead_keys.insert(names.index(name), a_key)

            # Receive HMAC from device
            elif (str(msg.payload.decode()).split(":")[0] == "hmac"):

                # Save received HMAC
                print("HMAC recibida del dispositivo.")
                h = str(msg.payload.decode()).split(":")[1]

                # If the device has just 'input'
                if (int(mode) == 0):
                    # DH or ECDH
                    if (asymmetric_mode == 0):
                        h2 = hmac.new(
                            bytes(hmac_key, 'ascii'),
                            bytes(str(b_public_key.public_numbers().y),
                                  'ascii'), hashlib.sha256)
                    else:
                        h2 = hmac.new(
                            bytes(hmac_key, 'ascii'),
                            b_public_key_ecdh.public_bytes(
                                encoding=Encoding.PEM,
                                format=PublicFormat.SubjectPublicKeyInfo),
                            hashlib.sha256)

                    # Compare HMAC
                    if (hmac.compare_digest(h, h2.hexdigest())):
                        hmacs.append(True)
                        data = {
                            "type": "datos_dispositivos",
                            "name": name,
                            "mode": mode
                        }
                        # Device will be added on web page if HMAC is correct
                        server.send_message_to_all(json.dumps(data))
                        print("HMAC de " + name +
                              " coincide. Añadiendo dispositivo...")
                    else:
                        hmacs.append(False)
                        # Unsubscribe
                        client.unsubscribe(name + "/from")
                        print("HMAC de " + name +
                              " no coincide. Dispositivo expulsado.")

            # Receive message from device
            elif (str(msg.payload.decode()).split(": ")[0] == "message"):
                message = str(msg.payload.decode()).split(": ")[1]

                # Fernet or AEAD
                if (symmetric_modes[names.index(name)] == 0):
                    message = fernet_keys[names.index(name)].decrypt(
                        message.encode())
                else:
                    message = aead_keys[names.index(name)].decrypt(
                        b"12345678", message.encode('latin-1'), None)
                print("Message from " + name + ": " + message.decode())

                # Show the correspondent information on web page
                data = {
                    "type": "message",
                    "name": name,
                    "payload": message.decode()
                }  # model data
                server.send_message_to_all(json.dumps(data))
示例#14
0
def decrypt_pk_dh(data, diffieHellmanExchange):
    try:
        rep = SPNEGO_PKINIT_AS_REP.load(bytes.fromhex(data)).native
    except:
        krb_message = KerberosResponse.load(bytes.fromhex(data))
        raise KerberosError(krb_message)

    relevantPadata = None
    for padata in rep['Kerberos']['padata']:
        if padata['padata-type'] == 17:
            relevantPadata = PA_PK_AS_REP.load(padata['padata-value']).native
            break

    if not relevantPadata:
        raise Exception('No PAdata found with type 17')
    keyinfo = SignedData.load(
        relevantPadata['dhSignedData']).native['encap_content_info']
    if keyinfo['content_type'] != '1.3.6.1.5.2.3.2':
        raise Exception('Keyinfo content type unexpected value')
    authdata = KDCDHKeyInfo.load(keyinfo['content']).native
    pubkey = int(
        ''.join(['1'] + [str(x) for x in authdata['subjectPublicKey']]), 2)

    pubkey = int.from_bytes(core.BitString(
        authdata['subjectPublicKey']).dump()[7:],
                            'big',
                            signed=False)
    shared_key = diffieHellmanExchange.exchange(pubkey)

    server_nonce = relevantPadata['serverDHNonce']
    fullKey = shared_key + diffieHellmanExchange.dh_nonce + server_nonce

    etype = rep['Kerberos']['enc-part']['etype']
    cipher = _enctype_table[etype]
    if etype == Enctype.AES256:
        t_key = truncate(fullKey, 32)
    elif etype == Enctype.AES128:
        t_key = truncate(fullKey, 16)
    elif etype == Enctype.RC4:
        raise NotImplementedError(
            'RC4 key truncation documentation missing. it is different from AES'
        )

    key = Key(cipher.enctype, t_key)
    enc_data = rep['Kerberos']['enc-part']['cipher']
    dec_data = cipher.decrypt(key, 3, enc_data)
    encasrep = EncASRepPart.load(dec_data).native
    cipher = _enctype_table[int(encasrep['key']['keytype'])]
    session_key = Key(cipher.enctype, encasrep['key']['keyvalue'])

    return session_key, cipher, rep

    # remove Octet String manualy
    padata = str(rep['padata'][0]['padata-value']).encode('hex')
    parsedPadata = decode(padata.decode('hex'), asn1Spec=AS_REP_Padata())[0]
    decoded = parsedPadata['DHRepInfo']['dhSignedData']
    kdcSignedDataResponse = decode(decoded, asn1Spec=SignedData())[0]
    kdcDHKeyInfo = str(kdcSignedDataResponse['encapContentInfo']
                       ['id-pkinit-authData-value']).encode('hex')
    d = decode(kdcDHKeyInfo.decode('hex'), asn1Spec=KDCDHKeyInfo())[0]
    dcPublicKey = int(encode(d['subjectPublicKey']).encode('hex')[20:], 16)

    dcPublicNumbers = dh.DHPublicNumbers(dcPublicKey, diffieHellmanExchange[2])

    backend = default_backend()

    dcPublicKey = backend.load_dh_public_numbers(dcPublicNumbers)
    shared_key = diffieHellmanExchange[1].exchange(dcPublicKey)
    sharedHexKey = shared_key.encode('hex')

    clientDHNonce = '6B328FA66EEBDFD3D69ED34E5007776AB30832A2ED1DCB1699781BFE0BEDF87A'
    serverDHNonce = encode(
        parsedPadata['DHRepInfo']['encKeyPack']).encode('hex')[8:]

    fullKey = sharedHexKey + clientDHNonce + serverDHNonce

    etype = rep['enc-part']['etype']
    cipher = _enctype_table[etype]
    if etype == Enctype.AES256:
        truncateKey = truncate(fullKey, 32)
        key = Key(cipher.enctype, truncateKey)

    elif etype == Enctype.AES128:
        truncateKey = truncate(fullKey, 16)
        key = Key(cipher.enctype, truncateKey)

    elif etype == Enctype.RC4:
        truncateKey = truncate(fullKey, 16)
        key = Key(cipher.enctype, truncateKey)

    cipherText = rep['enc-part']['cipher'].asOctets()
    plainText = cipher.decrypt(key, 3, cipherText)
    encASRepPart = decode(plainText, asn1Spec=EncASRepPart())[0]
    cipher = _enctype_table[int(encASRepPart['key']['keytype'])]
    session_key = Key(cipher.enctype,
                      encASRepPart['key']['keyvalue'].asOctets())
    return session_key, cipher, rep
示例#15
0
def registration(first_msg_obj, conn):
    # Check structure of first_msg_obj
    expected = ["reg"]
    real = sorted(list(first_msg_obj.keys()))
    if expected != real:
        print("Invalid message structure")
        put_message(conn, '{"error": "Invalid message structure"}')
        return

    parted_obj = first_msg_obj["reg"]
    # Check structure of parted_obj
    expected = ["iv", "part1", "part2"]
    real = sorted(list(parted_obj.keys()))
    if expected != real:
        print("Invalid message structure")
        put_message(conn, '{"error": "Invalid message structure"}')
        return

    # Decrypt part1
    globalized.debug("about to decrypt part1")
    part1_b64 = parted_obj["part1"]
    tup, error = part1_parts(part1_b64)
    if error:
        put_message(conn, error)
        return
    ts, username, secret_key, secret_key_b64 = tup
    ts_int = None
    try:
        ts_int = int(ts)
    except ValueError:
        print("timestamp is not int")
        put_message(conn, '{"error": "timestamp is not int"}')
        return

    globalized.debug("about to check time and username")
    now = int(time.time())
    if not (now - 2 * 60 < ts_int < now + 1 * 60):
        print("timestamp out of acceptable range")
        put_message(conn, '{"error": "timestamp out of acceptable range"}')
        return

    user = model.get_user(username)
    if user:
        print("username already exists")
        put_message(conn, '{"error": "username already exists"}')
        return

    # Get iv
    iv_b64 = parted_obj["iv"]
    iv, error = iv_from_b64(iv_b64)
    if error:
        put_message(conn, error)
        return

    # Decrypt part2
    globalized.debug("about to decrypt part2")
    part2_b64 = parted_obj["part2"]
    tup, error = part2_parts(part2_b64, secret_key, iv)
    if error:
        put_message(conn, error)
        return

    certificate, signature = tup

    # Verify signature
    to_hash = (ts + username + secret_key_b64).encode()
    pub_key = certificate.public_key()
    try:
        pub_key.verify(signature, to_hash, padding.PKCS1v15(), hashes.SHA256())
    except InvalidSignature:
        print("Invalid signature of part1")
        put_message(conn, '{"error": "Signature of part1 was invalid"}')
        return

    DH_parameters = dh.generate_parameters(5, 2048)
    DH_private = DH_parameters.generate_private_key()
    DH_public = DH_private.public_key()
    A = DH_public.public_numbers().y
    numbers = DH_parameters.parameter_numbers()
    g = numbers.g
    N = numbers.p

    to_sign = (ts + str(g) + str(N) + str(A)).encode()
    signature = sign_to_b64(to_sign)

    content_dic = {
        "ts": ts,
        "g": str(g),
        "N": str(N),
        "A": str(A),
        "signature": signature
    }
    content_bytes = json.dumps(content_dic).encode()
    iv2 = os.urandom(16)
    enc_content_b64 = aes_encrypt_to_b64(content_bytes, secret_key, iv2)

    msg_2_dic = {
        "content": enc_content_b64,
        "iv": base64.b64encode(iv2).decode()
    }
    msg_2 = json.dumps(msg_2_dic) + "\n"
    put_message(conn, msg_2)

    # Receive 3rd message
    message = None
    try:
        message = get_message(conn)
    except Exception as e:
        print(f"problem receiving 3rd message: {e}")
        put_message(conn, '{"error": "invalid 3rd message"}')
        return

    globalized.debug("checking parts of 3rd message")
    parts, error = parts_3rd_message(message, secret_key, pub_key)
    if error:
        put_message(conn, error)
        return

    B, new_username, new_ts = parts
    if new_username != username:
        print("username in 3rd message doesn't match")
        put_message(conn, '''{"error": "username doesn't match"}''')
        return
    if new_ts != ts:
        print("ts in 3rd message doesn't match")
        put_message(conn, '''{"error": "ts doesn't match"}''')
        return

    peer_public_numbers = dh.DHPublicNumbers(int(B), numbers)
    peer_public_key = peer_public_numbers.public_key()
    secret = DH_private.exchange(peer_public_key)

    # Store username, secret and certificate bytes
    res = model.add_user(username, secret,
                         certificate.public_bytes(serialization.Encoding.DER))

    # Send 4th message
    globalized.debug("preparing 4th message")
    resp = "OK" if res else "NO"
    to_sign = (ts + resp).encode()
    signature = sign_to_b64(to_sign)
    content_dic = {"ts": ts, "resp": resp, "signature": signature}
    content_bytes = json.dumps(content_dic).encode()
    iv4 = os.urandom(16)
    enc_content_b64 = aes_encrypt_to_b64(content_bytes, secret_key, iv4)

    msg_4_dic = {
        "content": enc_content_b64,
        "iv": base64.b64encode(iv4).decode()
    }
    msg_4 = json.dumps(msg_4_dic) + "\n"
    put_message(conn, msg_4)
示例#16
0
        # print(p)
        # print(g)
        parameters = pn.parameters(default_backend())
        private_key = parameters.generate_private_key()
        y_2 = private_key.public_key().public_numbers().y
        # print("Server y", y_2)
        # print("Client y", y)

        c.send(easy_bytes(y_2))
        pk_len = int.from_bytes(c.recv(1024), byteorder='little')
        if pk_len != len(easy_bytes(y_2)):
            print("mismatched data")
            s.close()
            exit(-1)

        peer_public_numbers = dh.DHPublicNumbers(y, pn)
        peer_public_key = peer_public_numbers.public_key(default_backend())
        shared_key = private_key.exchange(peer_public_key)
        derived_key = HKDF(
            algorithm=hashes.SHA256(),
            length=32,
            salt=None,
            info=b'handshake data',
            backend=default_backend()
        ).derive(shared_key)
        global_key = derived_key

        print("MITM Protection:", *random_emoji(int.from_bytes(derived_key,
                                                               byteorder='little'), UNICODE_VERSION), sep=' ')
    # g^b
示例#17
0
 def calc_shared_key(self, y):
     peer_public_number = dh.DHPublicNumbers(y, self.pn)
     peer_public_key = peer_public_number.public_key(default_backend())
     return self.private_key.exchange(peer_public_key)
示例#18
0
文件: server.py 项目: mikip65/ECS189M

def is_power_of_two(x):
    if x == 1:
        return True
    if x % 2 == 1:
        return False
    return is_power_of_two(x // 2)


if is_power_of_two(x):
    print(
        "Hey! Your exponent (private key) is so small I could've guessed it! Try to use a larger secure exponent instead!"
    )
    sys.exit()

pn = dh.DHParameterNumbers(p, 2)
peer = dh.DHPublicNumbers(x, params.parameter_numbers()).public_key(
    default_backend())
key = sk.exchange(peer)
print(
    "I have encrypted the flag by XORing it bitwise with our shared secret. Here it is:"
)


def xor(a, b):
    return bytes([x ^ y for x, y in zip(a, b)])


print(int.from_bytes(xor(key, flag.encode().rjust(len(key), b'\0')), "big"))
示例#19
0
 def compute_secret(self, peer_public_key):
     peer_public_key_int = int.from_bytes(peer_public_key, 'big')
     peer_public_numbers = dh.DHPublicNumbers(peer_public_key_int, self._pn)
     peer_public_key = peer_public_numbers.public_key(self.backend)
     self.shared_secret = self._private_key.exchange(peer_public_key)
    def process(self, msg=b""):
        """ Processa uma mensagem (`bytestring`) enviada pelo SERVIDOR.
            Retorna a mensagem a transmitir como resposta (`None` para
            finalizar ligação) """
        #primeiro p e g
        self.msg_cnt += 1
        if msg == b'':
            msg = mensagemboasvinda(self)
            return msg
        while len(msg) > 0:
            if msg:
                if (msg[:1] == b'E'): break
                if (msg[:1] == b'P'):
                    global derived_key_2
                    global public_key_file_server_serial
                    P = 99494096650139337106186933977618513974146274831566768179581759037259788798151499814653951492724365471316253651463342255785311748602922458795201382445323499931625451272600173180136123245441204133515800495917242011863558721723303661523372572477211620144038809673692512025566673746993593384600667047373692203583
                    G = 44157404837960328768872680677686802650999163226766694797650810379076416463147265401084491113667624054557335394761604876882446924929840681990106974314935015501571333024773172440352475358750668213444607353872754650805031912866692119819377041901642732455911509867728218394542745330014071040326856846990119719675
                    #ve qual é a chave publica DH server
                    public_key_server_dh = int(msg[1:].decode())
                    #dh do cliente
                    pn = dh.DHParameterNumbers(P, G)
                    parameters = pn.parameters(default_backend())
                    #criar private key dh do cliente
                    private_key_cliente_dh = parameters.generate_private_key()
                    #gerar public key dh do cliente
                    public_key_cliente_dh = private_key_cliente_dh.public_key(
                    ).public_numbers().y
                    #atraves da public key dh cria objeto para calcular chave Partilhada
                    peerPublicNumbers2 = dh.DHPublicNumbers(
                        public_key_server_dh, pn)
                    peer_key2 = peerPublicNumbers2.public_key(
                        default_backend())

                    #Lê o ficheiro p12 para extrair a sua chave privada
                    filepriv = open("privateKeyCli.pem", "rb")
                    keyprivateclii = filepriv.read()
                    filepriv.close()
                    #fazer serializacao chave privada ficheiro do cliente
                    private_key_file_cliente_serial = serialization.load_pem_private_key(
                        keyprivateclii,
                        password=None,
                        backend=default_backend())
                    #- Lê chave pública do ficheiro do servidor
                    filepub = open("publicKeySvr.pem", "rb")
                    keypublicread = filepub.read()
                    filepub.close()
                    #fazer serializacao chave publica ficheiro do SERVIDOR
                    public_key_file_server_serial = serialization.load_pem_public_key(
                        keypublicread, backend=default_backend())

                    clp12 = crypto.load_pkcs12(
                        open("client.p12", 'rb').read(), "xpto")
                    print(clp12)
                    clpem = getCertificado(clp12)
                    keyprivatecli = extractPrivate(clp12)
                    #concatenar chave publica dh server + chave publica dh cliente
                    gxgy = str(public_key_server_dh) + str(
                        public_key_cliente_dh)
                    global gyxx

                    gyxx = gxgy.encode()
                    #assinatura = gxgy + chave privada ficheiro cliente serial
                    signature = keyprivatecli.sign(
                        gyxx,
                        padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                    salt_length=padding.PSS.MAX_LENGTH),
                        hashes.SHA256())
                    public_key_cliente_dh_2 = str(
                        public_key_cliente_dh).encode()
                    #envia assinatura + certificado + chave pública
                    tmp = b'S' + signature + public_key_cliente_dh_2 + clpem
                    shared_key_2 = private_key_cliente_dh.exchange(peer_key2)
                    derived_key_2 = HKDF(
                        algorithm=hashes.SHA512(),
                        length=24,
                        salt=None,
                        info=b'handshake data',
                        backend=default_backend()).derive(shared_key_2)
                    print(signature)
                    print(public_key_cliente_dh_2)
                    print(clpem)
                    return tmp
                    #finito
                    #reopen
                if (msg[:1] == b'm'):
                    #- Recebe Assinatura
                    print("entra aqui")
                    vsign = msg[1:257]
                    svrpem = msg[257:]
                    print("here\n")
                    print(svrpem)
                    print("svrpem\n")
                    verificacao = verifica(svrpem)
                    if verificacao:
                        pub_svr = extractPublic(svrpem)
                        verifySignature(vsign, pub_svr, gyxx)
                        print('é seguro falarmos')
                        balhelhe = b'4'
                        return balhelhe
                    else:
                        print(signature)
                        print(public_key_cliente_dh)
                        print(clpem)
                        msg = b'S' + signature + clpem

                if (msg[:1] == b'4'):

                    iv_recebido = msg[1:17]  #chave de aes
                    mac_recebido = msg[17:49]
                    new_msg = msg[49:]

                    #imprime mensagem recebida
                    print('Received (%d): %r' % (1, msg))
                    print('Input message to send (empty to finish)')
                    new_msg_encode = input().encode()
                    iv_servido = os.urandom(16)
                    #encriptar
                    ct = encriptarcliente(keyaes, iv_servido, new_msg_encode)
                    #hmac
                    hmacfin = hmaccliente(keymac, ct)
                    #verificamac(self,msg,hmacfin,mac_recebido)
                    iv_cliente = os.urandom(16)
                    mensagem = b'C' + iv_servido + hmacfin + ct
                    return mensagem if len(mensagem) > 0 else None
                else:

                    #desencriptar

                    cipher = Cipher(algorithms.AES(keyaes),
                                    modes.CTR(iv_recebido),
                                    backend=backend)
                    decryptor = cipher.decryptor()
                    #hmac
                    hmacfin = hmacclienteelse(keymac, new_msg)
                    txt = decryptor.update(new_msg) + decryptor.finalize()
                    msg = txt.decode()
                    #verificamac(self,msg,hmacfin,mac_recebido)

                    #Função para verificar o hmac
                    #def verificamac(self,msg,hmacfin,mac_recebido,msgpv=b''):
                    if (hmacfin == mac_recebido):
                        print('Received (%d): %r' % (self.msg_cnt, msg))
                        print('Input message to send (empty to finish)')
                        new_msg_encode = input().encode()
                        iv_posve = os.urandom(16)
                        ct = encriptarelse(keyaes, iv_posve, new_msg_encode)
                        msgpv = iv_posve + hmacfin + ct
                        print(msgpv)
                        return msgpv if len(msgpv) > 0 else None
                    else:
                        print('deu erro, nao e igual')
示例#21
0
文件: deviceIoT.py 项目: pblprz/SPEA
def on_message(client, userdata, msg):
    global parameters
    global hmac_key
    global b_public_key_number
    global a_private_key
    global a_public_key
    global a_private_key_ecdh
    global a_public_key_ecdh
    global key_fernet
    global f_key
    global a_key

    if (msg.topic == (name + "/to")):

        # Receive params
        if (str(msg.payload.decode()).split(":")[0] == "param"):
            b_pem = str(msg.payload.decode()).split(":")[1]
            parameters = load_pem_parameters(bytes(b_pem, 'ascii'),
                                             backend=default_backend())

            # Calculate keys from params
            a_private_key = parameters.generate_private_key()
            a_public_key = a_private_key.public_key()
            client.publish(name + "/from",
                           "public:" + str(a_public_key.public_numbers().y))

        # Receive public key
        elif (str(msg.payload.decode()).split(":")[0] == "public"):
            print("Public key received from platform.")

            # DH
            if (asymmetric_mode == 0):
                b_public_key_number = int(
                    str(msg.payload.decode()).split(":")[1])
                peer_public_numbers = dh.DHPublicNumbers(
                    b_public_key_number, parameters.parameter_numbers())
                b_public_key = peer_public_numbers.public_key(
                    default_backend())
                # Calculate shared key
                a_shared_key = a_private_key.exchange(b_public_key)

            # ECDH
            else:
                # Generate private and public key ECDH
                a_private_key_ecdh = ec.generate_private_key(ec.SECP384R1())
                a_public_key_ecdh = a_private_key_ecdh.public_key()

                b_public_key_number = str(msg.payload.decode()).split(":")[1]
                b_public_key = load_pem_public_key(
                    b_public_key_number.encode())
                client.publish(
                    name + "/from", "public:" + a_public_key_ecdh.public_bytes(
                        encoding=Encoding.PEM,
                        format=PublicFormat.SubjectPublicKeyInfo).decode())
                # Calculate shared key
                a_shared_key = a_private_key_ecdh.exchange(
                    ec.ECDH(), b_public_key)

            print("Shared key calculated.")

            # Calculate HMAC
            def hebra():
                global hmac_key
                # If device has just 'input', write HMAC key here
                if (mode == 0):
                    hmac_key = str(
                        input(
                            "Introduce la clave que aparece en la plataforma: "
                        ))
                # If device has 'output' or nothing, write HMAC key on web page
                else:
                    hmac_key = str(os.urandom(2).hex())
                print("HMAC KEY: " + hmac_key)

                # Calcula HMAC (DH or ECDH)
                if (asymmetric_mode == 0):
                    h = hmac.new(
                        bytes(hmac_key, 'ascii'),
                        bytes(str(a_public_key.public_numbers().y), 'ascii'),
                        hashlib.sha256)
                else:
                    h = hmac.new(
                        bytes(hmac_key, 'ascii'),
                        a_public_key_ecdh.public_bytes(
                            encoding=Encoding.PEM,
                            format=PublicFormat.SubjectPublicKeyInfo),
                        hashlib.sha256)

                # Send to platform HMAC
                client.publish(name + "/from", "hmac:" + str(h.hexdigest()))

            if (hmac_key is None):
                # New thread because 'input' is blocking
                threading.Thread(target=hebra).start()

            # Calculate FERNET key using HASH
            derived_key_fernet = HKDF(
                algorithm=hashes.SHA256(),
                length=32,
                salt=None,
                info=b'handshake data').derive(a_shared_key)
            key_fernet = base64.urlsafe_b64encode(derived_key_fernet)
            f_key = Fernet(key_fernet)

            # Calculate AEAD key using HASH
            derived_key_aead = HKDF(
                algorithm=hashes.SHA256(),
                length=24,
                salt=None,
                info=b'handshake data').derive(a_shared_key)
            key_aead = base64.urlsafe_b64encode(derived_key_aead)
            a_key = aead.AESGCM(key_aead)