/// <summary> /// Raises this BigNum to a power and takes the modulus /// </summary> /// <param name="exp">The exponent</param> /// <param name="mod">Value to use when taking the modulus</param> /// <returns>this**exp % mod</returns> public BigNum PowMod(BigNum exp, BigNum mod) { if (fDisposed) throw new ObjectDisposedException("this"); if (exp.fDisposed) throw new ObjectDisposedException("exp"); if (mod.fDisposed) throw new ObjectDisposedException("mod"); IntPtr r = OpenSSL.BN_new(); IntPtr ctx = OpenSSL.BN_CTX_new(); OpenSSL.BN_mod_exp(r, fBigNum, exp.fBigNum, mod.fBigNum, ctx); OpenSSL.BN_CTX_free(ctx); return new BigNum(r); }
private byte[] ISetupKeys(plBufferedStream s, int gval) { BigNum b = BigNum.Random(512); BigNum n = new BigNum(fN); BigNum x = new BigNum(fX); // Calculate seeds BigNum client_seed = x.PowMod(b, n); BigNum server_seed = new BigNum(gval).PowMod(b, n); byte[] cliSeed = client_seed.ToLittleArray(); IWriteNetClientConnect(s, server_seed.ToLittleArray()); // Dispose of this crap... b.Dispose(); n.Dispose(); x.Dispose(); client_seed.Dispose(); server_seed.Dispose(); return cliSeed; }
/// <summary> /// Generates a random BigNum /// </summary> /// <param name="bits">How many bits the generated random number shoud have</param> /// <returns>Generated random number</returns> public static BigNum Random(int bits) { RNG.Seed(); BigNum rand = new BigNum(); OpenSSL.BN_rand(rand.fBigNum, bits, 1, 1); return rand; }
/// <summary> /// Replaces the content of the BigNum with a random BigNum /// </summary> /// <param name="bn">BigNum to replace</param> /// <param name="bits">How many bits the generated random number shoud have</param> public static void Random(BigNum bn, int bits) { if (bn.fDisposed) throw new ObjectDisposedException("BigNum"); RNG.Seed(); OpenSSL.BN_rand(bn.fBigNum, bits, 1, 1); }
static void IGenerateTheKey(string name, int g) { BigNum K = BigNum.GeneratePrime(512); BigNum N = BigNum.GeneratePrime(512); BigNum X = new BigNum(g).PowMod(K, N); // We store the keys as base64 strings in OpenSSL byte order (BE) string k = Convert.ToBase64String(K.ToBigArray()); string n = Convert.ToBase64String(N.ToBigArray()); string x = Convert.ToBase64String(X.ToBigArray()); Console.WriteLine(String.Format("Server.{0}.K \"{1}\"", name, k)); Console.WriteLine(String.Format("Server.{0}.N \"{1}\"", name, n)); Console.WriteLine(String.Format("Server.{0}.X \"{1}\"", name, x)); Console.WriteLine(); }
private bool ISetupKeys(int g) { BigNum b = new BigNum(Helpers.StrongRandom(64)); BigNum N = new BigNum(fN); BigNum X = new BigNum(fX); //Calculate seeds BigNum client_seed = X.PowMod(b, N); BigNum server_seed = new BigNum(g).PowMod(b, N); //Dump data fDhData = server_seed.ToArray(); fClientSeed = client_seed.ToArray(); //Explicitly dispose unmanaged OpenSSL resources b.Dispose(); N.Dispose(); X.Dispose(); client_seed.Dispose(); server_seed.Dispose(); return true; }
protected bool SetupEncryption(byte[] pubKey, byte[] privKey) { NetworkStream ns = new NetworkStream(fSocket, false); plBufferedStream temp = new plBufferedStream(ns); byte[] yData = IReadNetCliConnect(temp); if (yData != null) { BigNum Y = new BigNum(yData); BigNum N = new BigNum(pubKey); BigNum K = new BigNum(privKey); // Generate some randomness and do Y**K%N to get the key components byte[] server_seed = RNG.Random(7); BigNum client_seed = Y.PowMod(K, N); byte[] seed_data = client_seed.ToLittleArray(); // Grab the first 7 bytes and xor it with some randomness to make our key byte[] key = new byte[7]; for (int i = 0; i < key.Length; i++) if (i >= seed_data.Length) key[i] = server_seed[i]; else key[i] = (byte)(seed_data[i] ^ server_seed[i]); // Final setup fStream = new plBufferedStream(new pnSocketStream(fSocket, key)); IWriteNetCliEncrypt(temp, server_seed); // Explicitly clean up some resources so that we don't pressure the GC too much. // Those explicit finalizers really suck. Y.Dispose(); N.Dispose(); K.Dispose(); client_seed.Dispose(); } else // Write the error code to the unencrypted buffer temp.WriteByte(plNetCore.kNetCliError); temp.Flush(); temp.Close(); ns.Close(); return (yData != null); }