public static Lookup ( SrpStrength strength ) : |
||
strength | SrpStrength | the bit strength to lookup. |
return |
/// <summary> /// Creates a user credential from the provided data. /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="strength"></param> /// <param name="saltSize"></param> /// <param name="iterations"></param> /// <returns></returns> public SrpUserCredential(string username, string password, SrpStrength strength = SrpStrength.Bits1024, int saltSize = 32, int iterations = 4000) { username = username.Normalize(NormalizationForm.FormKC); password = password.Normalize(NormalizationForm.FormKC); UsernameBytes = Encoding.UTF8.GetBytes(username); var constants = SrpConstants.Lookup(strength); BigInteger N = constants.N; BigInteger g = constants.g; byte[] s = SaltGenerator.Create(saltSize); byte[] hashPassword = PBKDF2.ComputeSaltedPassword(HMACMethod.SHA512, Encoding.UTF8.GetBytes(password), s, iterations, 64); Sha512Digest hash = new Sha512Digest(); byte[] output = new byte[hash.GetDigestSize()]; hash.BlockUpdate(UsernameBytes, 0, UsernameBytes.Length); hash.Update((byte)':'); hash.BlockUpdate(hashPassword, 0, hashPassword.Length); hash.DoFinal(output, 0); hash.BlockUpdate(s, 0, s.Length); hash.BlockUpdate(output, 0, output.Length); hash.DoFinal(output, 0); BigInteger x = new BigInteger(1, output).Mod(N); BigInteger v = g.ModPow(x, N); UserName = username; Salt = s; Verification = v.ToByteArray(); Iterations = iterations; SrpStrength = strength; VerificationInteger = new BigInteger(1, Verification); }
void SetSrpStrength(SrpStrength strength) { m_strength = strength; m_srpByteLength = ((int)strength) >> 3; m_param = SrpConstants.Lookup(m_strength); m_client = new Srp6Client(m_param); }
private bool StandardAuthentication(IDigest hash, Stream stream, byte[] additionalChallenge) { // Authenticate (If mode = 1) // C <= S // byte PasswordHashMethod // byte SaltLength // byte[] Salt // int Iterations // byte SrpHashMethod // int Bit Strength // byte[] Public B (Size equal to SRP Length) // C => S // byte[] Public A (Size equal to SRP Length) // byte[] Client Proof: H(Public A | Public B | SessionKey) // C <= S // Bool Success (if false, done) // byte[] Server Proof: H(Public B | Public A | SessionKey) int srpNumberLength = ((int)m_user.SrpStrength) >> 3; stream.WriteByte((byte)PasswordHashMethod); stream.WriteByte((byte)m_user.Salt.Length); stream.Write(m_user.Salt); stream.Write(m_user.Iterations); stream.WriteByte((byte)SrpHashMethod); stream.Write((int)m_user.SrpStrength); stream.Flush(); //since computing B takes a long time. Go ahead and flush var param = SrpConstants.Lookup(m_user.SrpStrength); Srp6Server server = new Srp6Server(param, m_user.VerificationInteger); BigInteger pubB = server.GenerateServerCredentials(); byte[] pubBBytes = pubB.ToPaddedArray(srpNumberLength); stream.Write(pubBBytes); stream.Flush(); //Read from client: A byte[] pubABytes = stream.ReadBytes(srpNumberLength); BigInteger pubA = new BigInteger(1, pubABytes); //Calculate Session Key BigInteger S = server.CalculateSecret(hash, pubA); byte[] SBytes = S.ToPaddedArray(srpNumberLength); byte[] clientProofCheck = hash.ComputeHash(pubABytes, pubBBytes, SBytes, additionalChallenge); byte[] serverProof = hash.ComputeHash(pubBBytes, pubABytes, SBytes, additionalChallenge); byte[] clientProof = stream.ReadBytes(hash.GetDigestSize()); if (clientProof.SecureEquals(clientProofCheck)) { stream.Write(true); stream.Write(serverProof); stream.Flush(); byte[] K = hash.ComputeHash(pubABytes, SBytes, pubBBytes).Combine(hash.ComputeHash(pubBBytes, SBytes, pubABytes)); byte[] ticket = CreateSessionData(K, m_user); SessionSecret = K; stream.Write((short)ticket.Length); stream.Write(ticket); stream.Flush(); return(true); } stream.Write(false); stream.Flush(); return(false); }