Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 10 Jul 2013 14:09:06 +0200
From: marcus.desto <marcus.desto@...pl>
To: john-dev@...ts.openwall.com
Subject: Re: PBKDF2 hash_out 
	treatment

Hello magnum,


Dnia 10 lipca 2013 13:31 magnum <john.magnum@...hmail.com> napisaƂ(a):

> On 10 Jul, 2013, at 12:21 , marcus.desto <marcus.desto@...pl> wrote:
> > Hi Alexander,
> 
> That's not me :-)  My name is magnum (and only that - the "john" in my email address just refers to JtR).
> 

Oh, right. I am sorry. Solar is Alexander.

> OK. I think pbkdf2_hmac_sha1_unsplit_kernel.cl is better for your intentions and I'm pretty sure it does support running just one iteration. I also think it will return a normal byte sequence and it should be trivial to unpack it to a standard hex string.

Yeah.

> 
> Here's a test vector for pbkdf2-hmac-sha1 at one iteration:
> 
>      Input:
>        P = "password" (8 octets)
>        S = "salt" (4 octets)
>        c = 1
>        dkLen = 20
> 
>      Output:
>        DK = 0c 60 c8 0f 96 1f 0e 71
>             f3 a9 b5 24 af 60 12 06
>             2f e0 37 a6             (20 octets)
> 
> I take it your intention is to get that as a hex string of "0c60c80f961f0e71f3a9b524af6012062fe037a6", right?

Yes.

> 
> Please post a complete python program, as short/clean as possible, that just calculates this hard-coded test vector and prints the output, first using some prefab Python CPU function, and then (trying to) using pbkdf2_hmac_sha1_unsplit_kernel.cl. I'm sure we can help you get it straight from there.
> 
> magnum
> 

Alright, thanks. Please, refer to the attachment.

Marcus
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import struct
import math
import hashlib
import hmac  # RFC2104
from Crypto.Cipher import XOR

################ PBKDFv2


class PBKDFv2:

    ################ init
    def __init__(self):

        # length of pseudorandom function: 20 for SHA-1, 16 for MD5
        self.hLen = 20

    ################ makeKey
    def makeKey(self, P, S, c, dkLen, digesttype='sha1'):

        # do some sanity checks
        try:
            str(P)
            str(S)
            int(c)
            float(dkLen)
            int(c)
        except:
            print "P = %s, S = %s, c = %s, dkLen = %s:" % (P, S, c, dkLen)
            raise ValueError("ERROR! Input is not correct!")

        if dkLen > ((2 ^ 32 - 1) * self.hLen):
            maxlength = (2 ^ 32 - 1) * self.hLen
            raise ValueError("ERROR! Key is to large! Maxlength is " . str(maxlength))

        l = math.ceil(dkLen / float(self.hLen))

        T = ""
        for blockindex in range(int(l)):
            T += self.F(P, S, c, blockindex, digesttype)
        DK = T[:dkLen]

        return DK

    ################ F
    def F(self, P, S, c, i, digest):

        # The pseudorandom function, PRF, used is HMAC-SHA1 (rfc2104)
        iteration = 1

        # the first iteration; P is the key, and a concatination of
        # S and blocknumber is the message
        istr = struct.pack(">I", i + 1)
        PRFMaster = hmac.new(P, digestmod=getattr(hashlib, digest))
        PRF = PRFMaster.copy()
        PRF.update(S)
        PRF.update(istr)
        U = PRF.digest()  # the first iteration
        Fbuf = U

        while iteration < c:                  # loop through all iterations
            PRF = PRFMaster.copy()
            PRF.update(U)
            U = PRF.digest()
            Fbuf = self._xor(U, Fbuf)    # XOR this new iteration with the old one
            iteration += 1
        return Fbuf

    ################ xor
    def _xor(self, a, b):
        """Performs XOR on two strings a and b"""

        if len(a) != len(b):
            raise ValueError("ERROR: Strings are of different size! %s %s" % (len(a), len(b)))

        xor = XOR.new(a)
        return xor.encrypt(b)


####################################### MAIN ################################################
pbkdf = PBKDFv2()
# pbkdf.makeKey(password, passwordSalt, passwordIterations, keyBytes, 'sha1')
print "(CPU) PBKDFv2 Python output : "+str(''.join(x.encode('hex') for x in pbkdf.makeKey("password", "salt", 1, 20, 'sha1')))

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ