internal static BigInteger ComputeX(ClientInfo clientInfo, SrpInfo srpInfo) { var method = srpInfo.SrpMethod; var iterations = srpInfo.Iterations; if (iterations == 0) { throw new UnsupportedFeatureException("0 iterations is not supported"); } // TODO: Add constants for 1024, 6144 and 8192 if (method != "SRPg-4096") { throw new UnsupportedFeatureException($"Method '{method}' is not supported"); } var k1 = Util.Hkdf(method: method, ikm: srpInfo.Salt, salt: clientInfo.Username.ToBytes()); var k2 = Util.Pbes2(method: srpInfo.KeyMethod, password: clientInfo.Password, salt: k1, iterations: iterations); var x = clientInfo.AccountKey.CombineWith(k2); return(x.ToBigInt()); }
// // Internal // internal static byte[] Perform(BigInteger secretA, ClientInfo clientInfo, SrpInfo srpInfo, string sessionId, RestClient rest) { var sharedA = ComputeSharedA(secretA); var sharedB = ExchangeAForB(sharedA, sessionId, rest); ValidateB(sharedB); return(ComputeKey(secretA, sharedA, sharedB, clientInfo, srpInfo, sessionId)); }
internal static byte[] ComputeKey(BigInteger secretA, BigInteger sharedA, BigInteger sharedB, ClientInfo clientInfo, SrpInfo srpInfo, string sessionId) { // Some arbitrary crypto computation, variable names don't have a lot of meaning var ab = sharedA.ToHex() + sharedB.ToHex(); var hashAb = Crypto.Sha256(ab).ToBigInt(); var s = sessionId.ToBytes().ToBigInt(); var x = ComputeX(clientInfo, srpInfo); var y = sharedB - SirpG.ModExp(x, SirpN) * s; var z = y.ModExp(secretA + hashAb * x, SirpN); return(Crypto.Sha256(z.ToHex())); }
// Returns the session encryption key public static AesKey Perform(ClientInfo clientInfo, SrpInfo srpInfo, string sessionId, RestClient rest) { var key = Perform(GenerateSecretA(), clientInfo, srpInfo, sessionId, rest); return(new AesKey(sessionId, key)); }