/// <summary> /// Returns 32 byte array using SHA256 one-way hash of value S. /// RijndaelManaged, for example can use max key of 32 bytes directly, /// so this is convienent. If you need more or less entropy, add or subtract /// bytes as required. Naturally, both sides need to be able to generate the same /// key bytes. It is recommended to just use the 32 bytes as returned from this /// method. /// </summary> /// <param name="S"></param> /// <returns></returns> public static Byte[] CalcK(NetBigInteger S) { SHA256 sha256 = SHA256.Create(); Byte[] ba = sha256.ComputeHash(S.ToByteArray()); return(ba); }
/// <summary> /// Calculates k. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger Calck(NetBigInteger N, NetBigInteger g) { // k = SHA1(N | PAD(g)) SRP-6a Byte[] gBytes = g.ToByteArray(); Byte[] NBytes = N.ToByteArray(); Byte[] both = NetUtility.JoinArrays(NBytes, gBytes); Byte[] hash = hashAlgo.ComputeHash(both); return(new NetBigInteger(hash)); }
/// <summary> /// Calculates u. /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns></returns> public static NetBigInteger Calcu(NetBigInteger A, NetBigInteger B) { // Both: u = SHA1(PAD(A) | PAD(B)) Byte[] aBytes = A.ToByteArray(); Byte[] bBytes = B.ToByteArray(); Byte[] both = NetUtility.JoinArrays(aBytes, bBytes); Byte[] hash = hashAlgo.ComputeHash(both); return(new NetBigInteger(hash)); }
/// <summary> /// M2 is Server's proof of K. /// </summary> /// <returns></returns> public static Byte[] CalcM2(NetBigInteger A, Byte[] M, Byte[] K) { // Host -> User: H(A, M, K) Byte[] ABytes = A.ToByteArray(); ArrayList al = new ArrayList(); al.Add(ABytes); al.Add(M); al.Add(K); Byte[] all = NetUtility.JoinArrays(al); return(hashAlgo.ComputeHash(all)); }
/// <summary> /// This functions generates a database entry for the given username and password. It /// is key that this function can only be called from a safe environment and that the /// password is sent safely to this function. Think about SSL encryption or one time /// one way keys and so forth. Do your best! We actually generate these on the client /// so the password is NEVER sent over the network, and then sent it over an encrypted /// channel. /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="keysize"></param> /// <returns></returns> public static PlayerDatabaseEntry Generate(String username, String password, Int32 keysize) { Byte[] salt; // Calculates the verifier with a random salt // And we make sure the username is no longer case sensitive NetBigInteger verifier = Handshake.PasswordVerifier(username.ToLower().Trim(), password, keysize, out salt); // Returns the new entry return(new PlayerDatabaseEntry() { Username = username, Salt = salt, Verifier = verifier.ToByteArray() }); }
/// <summary> /// M is client's proof of K. /// </summary> /// <returns></returns> public static Byte[] CalcM(NetBigInteger N, NetBigInteger g, String userName, Byte[] salt, NetBigInteger A, NetBigInteger B, Byte[] K) { // User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) Byte[] gBytes = g.ToByteArray(); Byte[] NBytes = N.ToByteArray(); Byte[] hg = hashAlgo.ComputeHash(gBytes); Byte[] hN = hashAlgo.ComputeHash(NBytes); Byte[] gNXorBytes = XorArrays(hN, hg); Byte[] userNameBytes = Encoding.UTF8.GetBytes(userName); Byte[] hUserNameBytes = hashAlgo.ComputeHash(userNameBytes); Byte[] ABytes = A.ToByteArray(); Byte[] BBytes = B.ToByteArray(); ArrayList al = new ArrayList(); al.Add(gNXorBytes); al.Add(hUserNameBytes); al.Add(salt); al.Add(ABytes); al.Add(BBytes); al.Add(K); Byte[] all = NetUtility.JoinArrays(al); return(hashAlgo.ComputeHash(all)); }
/// <summary> /// Calculates u. /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns></returns> public static NetBigInteger Calcu(NetBigInteger A, NetBigInteger B) { // Both: u = SHA1(PAD(A) | PAD(B)) Byte[] aBytes = A.ToByteArray(); Byte[] bBytes = B.ToByteArray(); Byte[] both = NetUtility.JoinArrays(aBytes, bBytes); Byte[] hash = hashAlgo.ComputeHash(both); return new NetBigInteger(hash); }
/// <summary> /// M2 is Server's proof of K. /// </summary> /// <returns></returns> public static Byte[] CalcM2(NetBigInteger A, Byte[] M, Byte[] K) { // Host -> User: H(A, M, K) Byte[] ABytes = A.ToByteArray(); ArrayList al = new ArrayList(); al.Add(ABytes); al.Add(M); al.Add(K); Byte[] all = NetUtility.JoinArrays(al); return hashAlgo.ComputeHash(all); }
/// <summary> /// M is client's proof of K. /// </summary> /// <returns></returns> public static Byte[] CalcM(NetBigInteger N, NetBigInteger g, String userName, Byte[] salt, NetBigInteger A, NetBigInteger B, Byte[] K) { // User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) Byte[] gBytes = g.ToByteArray(); Byte[] NBytes = N.ToByteArray(); Byte[] hg = hashAlgo.ComputeHash(gBytes); Byte[] hN = hashAlgo.ComputeHash(NBytes); Byte[] gNXorBytes = XorArrays(hN, hg); Byte[] userNameBytes = Encoding.UTF8.GetBytes(userName); Byte[] hUserNameBytes = hashAlgo.ComputeHash(userNameBytes); Byte[] ABytes = A.ToByteArray(); Byte[] BBytes = B.ToByteArray(); ArrayList al = new ArrayList(); al.Add(gNXorBytes); al.Add(hUserNameBytes); al.Add(salt); al.Add(ABytes); al.Add(BBytes); al.Add(K); Byte[] all = NetUtility.JoinArrays(al); return hashAlgo.ComputeHash(all); }
/// <summary> /// Returns 32 byte array using SHA256 one-way hash of value S. /// RijndaelManaged, for example can use max key of 32 bytes directly, /// so this is convienent. If you need more or less entropy, add or subtract /// bytes as required. Naturally, both sides need to be able to generate the same /// key bytes. It is recommended to just use the 32 bytes as returned from this /// method. /// </summary> /// <param name="S"></param> /// <returns></returns> public static Byte[] CalcK(NetBigInteger S) { SHA256 sha256 = SHA256.Create(); Byte[] ba = sha256.ComputeHash(S.ToByteArray()); return ba; }
/// <summary> /// Calculates k. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger Calck(NetBigInteger N, NetBigInteger g) { // k = SHA1(N | PAD(g)) SRP-6a Byte[] gBytes = g.ToByteArray(); Byte[] NBytes = N.ToByteArray(); Byte[] both = NetUtility.JoinArrays(NBytes, gBytes); Byte[] hash = hashAlgo.ComputeHash(both); return new NetBigInteger(hash); }