Esempio n. 1
0
def _hmacedString(key, string):
    """
    Return the SHA-1 HMAC hash of the given key and string.
    """
    hash = HMAC(key, digestmod=sha)
    hash.update(string)
    return hash.digest()
Esempio n. 2
0
def _hmacedString(key, string):
    """
    Return the SHA-1 HMAC hash of the given key and string.
    """
    hash = HMAC(key, digestmod=sha)
    hash.update(string)
    return hash.digest()
Esempio n. 3
0
def compute_hash(key, pkt, pre=None, post=None):
    if (pre):
        h = HMAC(key, pre, Crypto.Hash.SHA)
        h.update(pkt)
    else:
        h = HMAC(key, pkt, Crypto.Hash.SHA)
    if post:
        h.update(post)
    return h.digest()
Esempio n. 4
0
def wrap(data, authKey, keyWrapKey):
    hmac = HMAC(authKey, digestmod=SHA256)
    hmac.update(data)
    kwa = hmac.digest()[:8]
    iv = os.urandom(16)
    cipher = AES.new(keyWrapKey, AES.MODE_CBC, iv)

    wrapped = cipher.encrypt(pad(data + kwa))
    wrapped = wrapped + iv
    return wrapped
Esempio n. 5
0
def mac_sign(kwargs=None, expires=None, key='', mac_len=0, mac_format='hex'):
    key = key or config.SIGN_KEY
    if not key:
        raise Exception('No key configured for signing the HMAC')
    if not kwargs:
        raise Exception('No message provided to be signed')
    if expires:
        kwargs['_expires'] = int(time() + expires)
    parts = ["%s=%s" % (key, kwargs[key]) for key in sorted(kwargs.keys())]
    msg = "&".join(parts)
    hmac = HMAC(str(key), msg=str(msg), digestmod=SHA256Hash())
    if mac_format == 'b64':
        tag = urlsafe_b64encode(hmac.digest()).rstrip('=')
    elif mac_format == 'bin':
        tag = hmac.digest()
    else:
        tag = hmac.hexdigest()
    if mac_len:
        tag = tag[:mac_len]
    kwargs['_mac'] = tag
Esempio n. 6
0
def unwrap(data, authKey, keyWrapKey):
    iv = data[-16:]
    cipher = AES.new(keyWrapKey, AES.MODE_CBC, iv)
    unwrapped = cipher.decrypt(data[:-16])
    unwrapped = unpad(unwrapped)

    kwa = unwrapped[-8:]
    unwrapped = unwrapped[:-8]

    hmac = HMAC(authKey, digestmod=SHA256)
    hmac.update(unwrapped)
    local_kwa = hmac.digest()[:8]

    if kwa != local_kwa:
        print("Unwrapped kwa does not match")

    return unwrapped
Esempio n. 7
0
def ExtractEntropySeed(rounds, username, password, salt=None):
    # Concentrates and then extracts the random entropy provided
    # by the password into a seed value for the first hash stage.

    # If if an explicit salt value is missing, use a hash of
    # the username as if it were the salt.
    if salt is None:
        salt = SHA512.new(username).digest()

    # Confirm the supplied salt meets the minimum length of 64
    # octets required, is aligned to a 32 octet boundary and does not
    # exceed 1,024 octets. Some implementations may not handle salt
    # values longer than 1,024 octets properly.
    elif len(salt) < 64:
        raise ValueError("The salt, if supplied, must be at least " \
          "64 octets in length.")
    elif operator.mod(len(salt), 32) != 0:
        warnings.warn("The salt, if longer than 64 octets, should " \
          "be aligned to a 32 octet boundary.")
    elif len(salt) > 1024:
        warnings.warn("The salt should not exceed 1,024 octets.")

    # For salt values which don't match the 128 octets required for
    # an HMAC key value, the salt is hashed twice using a 3 octet
    # counter value of 0 and 1, and the outputs are concatenated.
    if len(salt) != 128:
        key = \
            SHA512.new(salt + struct.pack('>I', 0)[1:4]).digest() + \
            SHA512.new(salt + struct.pack('>I', 1)[1:4]).digest()
    # If the supplied salt is 128 octets use it directly as the key value.
    else:
        key = salt

    # Initialize the HMAC instance using the key created above.
    hmac = HMAC(key, None, SHA512)

    # Repeat the plaintext password successively based on
    # the number of instances specified by the rounds variable.
    for unused in range(0, rounds):
        hmac.update(password)

    # Create the 64 octet seed value.
    seed = hmac.digest()

    return seed
Esempio n. 8
0
def ExtractEntropySeed(rounds, username, password, salt=None):
    # Concentrates and then extracts the random entropy provided
    # by the password into a seed value for the first hash stage.

    # If if an explicit salt value is missing, use a hash of
    # the username as if it were the salt.
    if salt is None:
        salt = SHA512.new(username).digest()

    # Confirm the supplied salt meets the minimum length of 64
    # octets required, is aligned to a 32 octet boundary and does not
    # exceed 1,024 octets. Some implementations may not handle salt
    # values longer than 1,024 octets properly.
    elif len(salt) < 64:
        raise ValueError("The salt, if supplied, must be at least " \
          "64 octets in length.")
    elif operator.mod(len(salt), 32) != 0:
        warnings.warn("The salt, if longer than 64 octets, should " \
          "be aligned to a 32 octet boundary.")
    elif len(salt) > 1024:
        warnings.warn("The salt should not exceed 1,024 octets.")

    # For salt values which don't match the 128 octets required for
    # an HMAC key value, the salt is hashed twice using a 3 octet
    # counter value of 0 and 1, and the outputs are concatenated.
    if len(salt) != 128:
        key = \
            SHA512.new(salt + struct.pack('>I', 0)[1:4]).digest() + \
            SHA512.new(salt + struct.pack('>I', 1)[1:4]).digest()
    # If the supplied salt is 128 octets use it directly as the key value.
    else:
        key = salt

    # Initialize the HMAC instance using the key created above.
    hmac = HMAC(key, None, SHA512)

    # Repeat the plaintext password successively based on
    # the number of instances specified by the rounds variable.
    for unused in range(0, rounds):
        hmac.update(password)

    # Create the 64 octet seed value.
    seed = hmac.digest()

    return seed
Esempio n. 9
0
    def register(self):
        """
        Gets authentication info from a DPT-RP1.  You can call this BEFORE
        DigitalPaper.authenticate()

        Returns (ca, priv_key, client_id):
            - ca: a PEM-encoded X.509 server certificate, issued by the CA
                  on the device
            - priv_key: a PEM-encoded 2048-bit RSA private key
            - client_id: the client id
        """

        reg_url = "http://{addr}:8080".format(addr=self.addr)
        register_pin_url = "{base_url}/register/pin".format(base_url=reg_url)
        register_hash_url = "{base_url}/register/hash".format(base_url=reg_url)
        register_ca_url = "{base_url}/register/ca".format(base_url=reg_url)
        register_url = "{base_url}/register".format(base_url=reg_url)
        register_cleanup_url = "{base_url}/register/cleanup".format(
            base_url=reg_url)

        print("Cleaning up...")
        r = self.session.put(register_cleanup_url)
        print(r)

        print("Requesting PIN...")
        r = self.session.post(register_pin_url)
        m1 = r.json()

        n1 = base64.b64decode(m1["a"])
        mac = base64.b64decode(m1["b"])
        yb = base64.b64decode(m1["c"])
        yb = int.from_bytes(yb, "big")
        n2 = os.urandom(16)  # random nonce

        dh = DiffieHellman()
        ya = dh.gen_public_key()
        ya = b"\x00" + ya.to_bytes(256, "big")

        zz = dh.gen_shared_key(yb)
        zz = zz.to_bytes(256, "big")
        yb = yb.to_bytes(256, "big")

        derivedKey = PBKDF2(passphrase=zz,
                            salt=n1 + mac + n2,
                            iterations=10000,
                            digestmodule=SHA256).read(48)

        authKey = derivedKey[:32]
        keyWrapKey = derivedKey[32:]

        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(n1 + mac + yb + n1 + n2 + mac + ya)
        m2hmac = hmac.digest()

        m2 = dict(
            a=base64.b64encode(n1).decode("utf-8"),
            b=base64.b64encode(n2).decode("utf-8"),
            c=base64.b64encode(mac).decode("utf-8"),
            d=base64.b64encode(ya).decode("utf-8"),
            e=base64.b64encode(m2hmac).decode("utf-8"),
        )

        print("Encoding nonce...")
        r = self.session.post(register_hash_url, json=m2)
        m3 = r.json()

        if base64.b64decode(m3["a"]) != n2:
            print("Nonce N2 doesn't match")
            return

        eHash = base64.b64decode(m3["b"])
        m3hmac = base64.b64decode(m3["e"])
        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(n1 + n2 + mac + ya + m2hmac + n2 + eHash)
        if m3hmac != hmac.digest():
            print("M3 HMAC doesn't match")
            return

        pin = input("Please enter the PIN shown on the DPT-RP1: ")

        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(pin.encode())
        psk = hmac.digest()

        rs = os.urandom(16)  # random nonce
        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(rs + psk + yb + ya)
        rHash = hmac.digest()

        wrappedRs = wrap(rs, authKey, keyWrapKey)

        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(n2 + eHash + m3hmac + n1 + rHash + wrappedRs)
        m4hmac = hmac.digest()

        m4 = dict(
            a=base64.b64encode(n1).decode("utf-8"),
            b=base64.b64encode(rHash).decode("utf-8"),
            d=base64.b64encode(wrappedRs).decode("utf-8"),
            e=base64.b64encode(m4hmac).decode("utf-8"),
        )

        print("Getting certificate from device CA...")
        r = self.session.post(register_ca_url, json=m4)
        print(r)

        m5 = r.json()

        if base64.b64decode(m5["a"]) != n2:
            print("Nonce N2 doesn't match")
            return

        wrappedEsCert = base64.b64decode(m5["d"])
        m5hmac = base64.b64decode(m5["e"])

        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(n1 + rHash + wrappedRs + m4hmac + n2 + wrappedEsCert)
        if hmac.digest() != m5hmac:
            print("HMAC doesn't match!")
            return

        esCert = unwrap(wrappedEsCert, authKey, keyWrapKey)
        es = esCert[:16]
        cert = esCert[16:]

        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(es + psk + yb + ya)
        if hmac.digest() != eHash:
            print("eHash does not match!")
            return

        # print("Certificate: ")
        # print(cert)

        print("Generating RSA2048 keys")
        new_key = RSA.generate(2048, e=65537)

        # with open("key.pem", 'wb') as f:
        #    f.write(new_key.exportKey("PEM"))

        keyPubC = new_key.publickey().exportKey("PEM")

        selfDeviceId = str(uuid.uuid4())
        print("Device ID: " + selfDeviceId)
        selfDeviceId = selfDeviceId.encode()

        # with open("client_id.txt", 'wb') as f:
        #    f.write(selfDeviceId)

        wrappedDIDKPUBC = wrap(selfDeviceId + keyPubC, authKey, keyWrapKey)

        hmac = HMAC(authKey, digestmod=SHA256)
        hmac.update(n2 + wrappedEsCert + m5hmac + n1 + wrappedDIDKPUBC)
        m6hmac = hmac.digest()

        m6 = dict(
            a=base64.b64encode(n1).decode("utf-8"),
            d=base64.b64encode(wrappedDIDKPUBC).decode("utf-8"),
            e=base64.b64encode(m6hmac).decode("utf-8"),
        )

        print("Registering device...")
        r = self.session.post(register_url, json=m6)
        print(r)

        print("Cleaning up...")
        r = self.session.put(register_cleanup_url)
        print(r)

        return (
            cert.decode("utf-8"),
            new_key.exportKey("PEM").decode("utf-8"),
            selfDeviceId.decode("utf-8"),
        )