Exemple #1
0
def new(password, server=defaultServer, clientId=None, username="******"):
    """
    Encrypts a new @password by interacting with the Pythia service.
    @clientId: If specified, this value is used. If omitted, a suitable 
               value is selected.

    @returns a tuple of required values to verify the password: (w,t,z,p) 
     where:
        @w: client ID (key selector)
        @t: tweak (randomly generated user ID)
        @z: protected passwords
        @p: server public key bound to clientId - used to verify future
            proofs from this server.
    """
    # Set the client ID
    if not clientId:
        w = secureRandom()
    else:
        w = clientId

    if ersatzHash == True:
        ersatzPw = "ersatz"
        ersatzHashGen = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha1,\
                                                      username, password, \
                                                      ersatzPw, rounds=5000)
        #create ersatz salt
        t = ersatzHashGen._compute_ersatz_salt(password, ersatzPw)
        ersatzHashGen.salt = t
        a = ersatzHashGen._compute_ersatz_hash(password)
        a = passlib.utils.ab64_decode(a)

        #create ersatz input
        ersatzInput = ersatzHashGen._ersatzfy_input(password)
        z, p = query(ersatzInput, w, t, server)

        z = vpop.wrap(
            pyrelic.vpop.update(vpop.unwrapY(z), long(a.encode('hex'), 16)))
        #do the Z^a nonsense, where a is the pbkdf2

    else:
        t = secureRandom()

        hashedPW = pbkdf2_sha1.encrypt(password, salt=t, rounds=5000)
        z, p = query(hashedPW, w, t, server)
        z = vpop.wrap(
            pyrelic.vpop.update(vpop.unwrapY(z),
                                long(hashedPW.encode('hex'), 16)))
        #t = secureRandom()
        #z,p = query(password, w, t, server)
    return w, t, z, p
Exemple #2
0
def check(password, w, t, z, p, server=defaultServer, username="******"):
    """
    Checks an existing @password against the Pythia server using the 
    values (w,t,z,p).
    @returns: True if the password passes authentication; False otherwise.
    """

    if ersatzHash:
        ersatzHashGen = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha1,\
                                                      username, password, \
                                                      "ersatz", rounds=5000)
        ersatzHashGen.salt = t
        ersatzInput = ersatzHashGen._ersatzfy_input(password)

        #check true password
        zPrime1, _ = query(ersatzInput, w, t, previousPubkey=p, server=server)
        zPrime2, _ = query(password, w, t, previousPubkey=p, server=server)

        #create ersatz salt
        a = passlib.utils.ab64_decode(
            ersatzHashGen._compute_ersatz_hash(password))

        zPrime1 = vpop.wrap(
            pyrelic.vpop.update(vpop.unwrapY(zPrime1),
                                long(a.encode('hex'), 16)))

        a = passlib.utils.ab64_decode(
            hash.pbkdf2_sha1.encrypt(password, salt=t, rounds=5000))
        zPrime2 = vpop.wrap(
            pyrelic.vpop.update(vpop.unwrapY(zPrime2),
                                long(a.encode('hex'), 16)))

        if z == zPrime1:
            return 1
        elif z == zPrime2:
            return 2
        else:
            return 0
        #check ersatz password
    else:
        hashedPW = pbkdf2_sha1.encrypt(password, salt=t, rounds=5000)
        zPrime, _ = query(hashedPW, w, t, previousPubkey=p, server=server)
        zPrime = vpop.wrap(
            pyrelic.vpop.update(vpop.unwrapY(zPrime),
                                long(hashedPW.encode('hex'), 16)))

        #zPrime,_ = query(password, w, t, previousPubkey=p, server=server)
        return z == zPrime
Exemple #3
0
def new(password, server=defaultServer, clientId=None, username="******"):
    """
    Encrypts a new @password by interacting with the Pythia service.
    @clientId: If specified, this value is used. If omitted, a suitable 
               value is selected.

    @returns a tuple of required values to verify the password: (w,t,z,p) 
     where:
        @w: client ID (key selector)
        @t: tweak (randomly generated user ID)
        @z: protected passwords
        @p: server public key bound to clientId - used to verify future
            proofs from this server.
    """
    # Set the client ID
    if not clientId:
        w = secureRandom()
    else:
        w = clientId
    
    if ersatzHash == True:
        ersatzPw = "ersatz"
        ersatzHashGen = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha1,\
                                                      username, password, \
                                                      ersatzPw, rounds=5000)
        #create ersatz salt
        t = ersatzHashGen._compute_ersatz_salt(password,ersatzPw)
        ersatzHashGen.salt = t
        a = ersatzHashGen._compute_ersatz_hash(password)
        a = passlib.utils.ab64_decode(a)
        
        #create ersatz input
        ersatzInput = ersatzHashGen._ersatzfy_input(password)
        z,p = query(ersatzInput, w, t, server)
        
        z = vpop.wrap(pyrelic.vpop.update(vpop.unwrapY(z), long(a.encode('hex'),16)))
        #do the Z^a nonsense, where a is the pbkdf2
        
    else:
        t = secureRandom()

        hashedPW = pbkdf2_sha1.encrypt(password, salt=t, rounds=5000)
        z,p = query(hashedPW, w, t, server)
        z = vpop.wrap(pyrelic.vpop.update(vpop.unwrapY(z), long(hashedPW.encode('hex'),16)))
        #t = secureRandom()
        #z,p = query(password, w, t, server)
    return w, t, z, p
Exemple #4
0
def update(wPrime,w,t,z,p,server=defaultServer):
    # Query the service via HTTP(S) GET
    response = fetch(queryUrlUpdateTemplate.format(server,w,wPrime))
    
    # Grab the required fields from the response.
    pPrime,delta = extract(response, ["pPrime","delta"])
    updatedZ = vpop.wrap(pyrelic.vpop.update(vpop.unwrapY(z), pyrelic.vpop.unwrapDelta(delta)))
    updateP = vpop.wrap(vpop.unwrapP(p)*vpop.unwrapLong(delta))
    return wPrime, t, updatedZ, updateP
Exemple #5
0
def update(wPrime, w, t, z, p, server=defaultServer):
    # Query the service via HTTP(S) GET
    response = fetch(queryUrlUpdateTemplate.format(server, w, wPrime))

    # Grab the required fields from the response.
    pPrime, delta = extract(response, ["pPrime", "delta"])
    updatedZ = vpop.wrap(
        pyrelic.vpop.update(vpop.unwrapY(z), pyrelic.vpop.unwrapDelta(delta)))
    updateP = vpop.wrap(vpop.unwrapP(p) * vpop.unwrapLong(delta))
    return wPrime, t, updatedZ, updateP
Exemple #6
0
def check(password, w, t, z, p, server=defaultServer, username="******"):
    """
    Checks an existing @password against the Pythia server using the 
    values (w,t,z,p).
    @returns: True if the password passes authentication; False otherwise.
    """
    
    if ersatzHash:
        ersatzHashGen = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha1,\
                                                      username, password, \
                                                      "ersatz", rounds=5000)
        ersatzHashGen.salt = t
        ersatzInput = ersatzHashGen._ersatzfy_input(password)
        
        #check true password
        zPrime1,_ = query(ersatzInput, w, t, previousPubkey=p, server=server)
        zPrime2,_ = query(password, w, t, previousPubkey=p, server=server)
        

        #create ersatz salt
        a = passlib.utils.ab64_decode(ersatzHashGen._compute_ersatz_hash(password))
        
        zPrime1 = vpop.wrap(pyrelic.vpop.update(vpop.unwrapY(zPrime1), long(a.encode('hex'),16)))
        
        a = passlib.utils.ab64_decode(hash.pbkdf2_sha1.encrypt(password, salt=t, rounds=5000))
        zPrime2 = vpop.wrap(pyrelic.vpop.update(vpop.unwrapY(zPrime2), long(a.encode('hex'),16)))
        
        if z == zPrime1:
            return 1
        elif z == zPrime2:
            return 2
        else:
            return 0
        #check ersatz password
    else:
        hashedPW = pbkdf2_sha1.encrypt(password, salt=t, rounds=5000)
        zPrime,_ = query(hashedPW, w, t, previousPubkey=p, server=server)
        zPrime = vpop.wrap(pyrelic.vpop.update(vpop.unwrapY(zPrime), long(hashedPW.encode('hex'),16)))
        
        #zPrime,_ = query(password, w, t, previousPubkey=p, server=server)
        return z == zPrime
Exemple #7
0
    def eval(self,w,t,pw):
        """
        Runs an eval and returns the result.
        """
        # Blind and serialize the pw
        r,x = vpop.blind(pw)
        x = vpop.wrap(x)

        # Call the URL and verify the response
        response = self.client.get(VpopAdvTest.urlEval.format(w,t,x))
        ySerial = str(self.check(response, "y"))

        # Deserialize and de-blind the result.
        y = vpop.unwrapY(ySerial)
        return vpop.deblind(r,y)
Exemple #8
0
    def testProof(self):
        """
        Ensures the proof is valid.
        """
        # Make an eval request
        r,x = vpop.blind(pw)
        xWrap = vpop.wrap(x)
        url = VpopEvalTest.urlTemplate.format(w,t,xWrap)
        r = self.parseResponse(self.client.get(url))

        # Deserialize the items needed to verify the proof.
        y = vpop.unwrapY(r["y"])
        pi = (vpop.unwrapP(r["p"]), vpop.unwrapC(r["c"]), vpop.unwrapU(r["u"]) )

        # Test the proof
        self.assertTrue( vpop.verify(x, t, y, pi) )
Exemple #9
0
def query(password, w, t, server=defaultServer, previousPubkey=None):
    """
    Queries the a Pythia PRF service and verifies the server's ZKP.
    @returns (z,p) where: @z is the encrypted password and @p is the
        server's pubkey bound to clientId

    Raises an exception if there are any problems interacting with the service
        or if the server's ZKP fails verification.
    """
    # Blind the password
    r, x = vpop.blind(password)
    xSerialized = vpop.wrap(x)

    # Query the service via HTTP(S) GET
    response = fetch(queryUrlTemplate.format(server, w, t, xSerialized))

    # Grab the required fields from the response.
    p, y, c, u = extract(response, ["p", "y", "c", "u"])

    # Check the pubkey
    if previousPubkey and previousPubkey != p:
        print "previous: " + previousPubkey
        print "p: " + p
        raise Exception(
            "Server-provided pubkey doesn't match previous pubkey.")

    # Deserialize the response fields
    p, y, c, u = (vpop.unwrapP(p), vpop.unwrapY(y), vpop.unwrapC(c),
                  vpop.unwrapU(u))

    pi = (p, c, u)

    # Verify the result by checking the proof
    vpop.verify(x, t, y, pi)

    # Deblind the result
    z = vpop.deblind(r, y)

    # Return the important fields in serialied form
    z, p = vpop.wrap(z), vpop.wrap(p)
    return z, p
Exemple #10
0
def query(password, w, t, server=defaultServer, previousPubkey=None):
    """
    Queries the a Pythia PRF service and verifies the server's ZKP.
    @returns (z,p) where: @z is the encrypted password and @p is the
        server's pubkey bound to clientId

    Raises an exception if there are any problems interacting with the service
        or if the server's ZKP fails verification.
    """
    # Blind the password
    r,x = vpop.blind(password)
    xSerialized = vpop.wrap(x)

    # Query the service via HTTP(S) GET
    response = fetch(queryUrlTemplate.format(server,w,t,xSerialized))

    # Grab the required fields from the response.
    p,y,c,u = extract(response, ["p","y","c","u"])

    # Check the pubkey
    if previousPubkey and previousPubkey != p:
        print "previous: " + previousPubkey
        print "p: "+ p
        raise Exception("Server-provided pubkey doesn't match previous pubkey.")

    # Deserialize the response fields
    p,y,c,u = (vpop.unwrapP(p), vpop.unwrapY(y), 
            vpop.unwrapC(c), vpop.unwrapU(u))

    pi = (p,c,u)

    # Verify the result by checking the proof
    vpop.verify(x, t, y, pi)

    # Deblind the result
    z = vpop.deblind(r,y)

    # Return the important fields in serialied form
    z,p = vpop.wrap(z), vpop.wrap(p)
    return z,p