CHAP with different behaviour on different machines
<p>I am developing an android app that uses RESTful services to communicate with the server. For the login i use the CHAP method. </p>

<ul>
<li>On machine one (Win7 32bit) the login works</li>
<li>On machine two (Win7 64bit) the login doesn't work</li>
</ul>

<p>Here is the code i use:</p>

<p>Serverside (C#):</p>

<pre><code>public string AuthenticateByPassword(string authUserName, long crcvalue)
    {
        if (!CHAPUtil.CheckAuth(authUserName, crcvalue))
            throw new PermissionDeniedException();

        return masterdata.AuthenticateByPassword(authUserName, CHAPUtil.getPasswordByUsername(authUserName));
    }

public long getAuthentificationChallenge(string username)
    {
        long challenge = CHAPUtil.getChallenge();
        CHAPUtil.CalculateHash(username, challenge);
        return challenge;
    }

public class CHAPUtil
{
    private static Hashtable crcValues = new Hashtable();

    public static long getChallenge()
    {
        Random r = new Random();
        return r.Next();
    }

    public static void CalculateHash(string username, long random)
    {
        Crc32 crc = new Crc32();
        long crcResult = crc.ComputeChecksum(StringToByteArray(getPasswordByUsername(username)));

        if (crcValues.Contains(username))
        {
            crcValues.Remove(username);
        }

        crcValues.Add(username, crcResult * random);
    }

    public static bool CheckAuth(string username, long hashvalue)
    {
        if (crcValues.Contains(username))
        {
            long value = (long)crcValues[username];
            if (value == hashvalue)
            {
                crcValues.Remove(username);
                return true;
            }
        }
        return false;
    }

    public static string getPasswordByUsername(string username)
    {            
    }

    private static byte[] StringToByteArray(string str)
    {
        System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
        return enc.GetBytes(str);
    }
}

public class Crc32
{
    uint[] table;

    public long ComputeChecksum(byte[] bytes)
    {
        uint crc = 0xffffffff;
        for (int i = 0; i &lt; bytes.Length; ++i)
        {
            byte index = (byte)(((crc) &amp; 0xff) ^ bytes[i]);
            crc = (uint)((crc &gt;&gt; 8) ^ table[index]);
        }
        return ~crc;
    }

    public byte[] ComputeChecksumBytes(byte[] bytes)
    {
        return BitConverter.GetBytes(ComputeChecksum(bytes));
    }

    public Crc32()
    {
        uint poly = 0xedb88320;
        table = new uint[256];
        uint temp = 0;
        for (uint i = 0; i &lt; table.Length; ++i)
        {
            temp = i;
            for (int j = 8; j &gt; 0; --j)
            {
                if ((temp &amp; 1) == 1)
                {
                    temp = (uint)((temp &gt;&gt; 1) ^ poly);
                }
                else
                {
                    temp &gt;&gt;= 1;
                }
            }
            table[i] = temp;
        }
    }
}
</code></pre>

<p>Clientside (Java/Android)</p>

<pre><code>private static String login(String username, String passwd) {

    //Challenge handshake authentification
    //1st step - get authentification challenge (random long)
    long challenge = MasterdataServices.getAuthentificationChallenge(username);
    if(challenge == 0 || challenge == -1) {
        return null;
    }

    //get hashed password
    String hashedPassword = getHashedPassword(passwd);

    //2nd step - get crc value
    long crcValue = getCrcValue(hashedPassword, challenge);

    //3rd step - get session token
    String sessionId = MasterdataServices.authenticateByPassword(username, crcValue);
    return sessionId;
}

private static long getCrcValue(String password, long challengeValue) {
    CRC32 crc = new CRC32();
    try {
        crc.update(password.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }       
    return crc.getValue() * challengeValue;
}   

private static String getHashedPassword(String password) {
    MessageDigest messageDigest = null;
    try {
        messageDigest = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
    byte[] encryptedPw = null;
    try {
        encryptedPw = messageDigest.digest(password.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return null;
    }
    StringBuilder hex = new StringBuilder(encryptedPw.length * 2);

    for(byte b : encryptedPw)
    {
        if((b &amp; 0xff) &lt; 0x10) hex.append("0");
        hex.append(Integer.toHexString(b &amp; 0xff));
    }               

    return hex.toString();
}   
</code></pre>

<p>Does anyone know where the differences might come from?</p>
