Metin2 Diffie Hellman Class, Packet Encryption

06/29/2014 21:15 falchonn#1
Hello guys, lets think there is a static p, g, q values for Diffie hellman.

Server sends to client 256 bytes data and client process it and sends new data with 256 bytes to server:

Code:
size_t DH2KeyAgreement::Prepare(void* buffer, size_t* length) {
#ifdef __THEMIDA__
	VM_START
#endif

	// RFC 5114, 1024-bit MODP Group with 160-bit Prime Order Subgroup
	// http://tools.ietf.org/html/rfc5114#section-2.1
	Integer p("0xB10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
		"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
		"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
		"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
		"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
		"DF1FB2BC2E4A4371");

	Integer g("0xA4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
		"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
		"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
		"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
		"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
		"855E6EEB22B3B2E5");

	Integer q("0xF518AA8781A8DF278ABA4E7D64B7CB9D49462353");

	// Schnorr Group primes are of the form p = rq + 1, p and q prime. They
	// provide a subgroup order. In the case of 1024-bit MODP Group, the
	// security level is 80 bits (based on the 160-bit prime order subgroup).		

	// For a compare/contrast of using the maximum security level, see
	// dh-unified.zip. Also see http://www.cryptopp.com/wiki/Diffie-Hellman
	// and http://www.cryptopp.com/wiki/Security_level .

	AutoSeededRandomPool rnd;

	dh_.AccessGroupParameters().Initialize(p, q, g);

	if(!dh_.GetGroupParameters().ValidateGroup(rnd, 3)) {
		// Failed to validate prime and generator
		return 0;
	}

	size_t count = 0;

	p = dh_.GetGroupParameters().GetModulus();
	q = dh_.GetGroupParameters().GetSubgroupOrder();
	g = dh_.GetGroupParameters().GetGenerator();

	// http://groups.google.com/group/sci.crypt/browse_thread/thread/7dc7eeb04a09f0ce
	Integer v = ModularExponentiation(g, q, p);

	if(v != Integer::One()) {
		// Failed to verify order of the subgroup
		return 0;
	}

	//////////////////////////////////////////////////////////////

	spriv_key_.New(dh2_.StaticPrivateKeyLength());
	epriv_key_.New(dh2_.EphemeralPrivateKeyLength());
	SecByteBlock spub_key(dh2_.StaticPublicKeyLength());
	SecByteBlock epub_key(dh2_.EphemeralPublicKeyLength());

	dh2_.GenerateStaticKeyPair(rnd, spriv_key_, spub_key);
	dh2_.GenerateEphemeralKeyPair(rnd, epriv_key_, epub_key);

	// Prepare key agreement data
	const size_t spub_key_length = spub_key.size();
	const size_t epub_key_length = epub_key.size();
	const size_t data_length = spub_key_length + epub_key_length;

	if (*length < data_length) {
		// Not enough data buffer length
		return 0;
	}

	*length = data_length;
	byte* buf = (byte*)buffer;
	memcpy(buf, spub_key.BytePtr(), spub_key_length);
	memcpy(buf + spub_key_length, epub_key.BytePtr(), epub_key_length);

#ifdef __THEMIDA__
	VM_END
#endif

	return dh2_.AgreedValueLength();
}
then agrees data:

Code:
bool DH2KeyAgreement::Agree(size_t agreed_length, const void* buffer, size_t length) {
	if (agreed_length != dh2_.AgreedValueLength()) {
		// Shared secret size mismatch
		return false;
	}
	const size_t spub_key_length = dh2_.StaticPublicKeyLength();
	const size_t epub_key_length = dh2_.EphemeralPublicKeyLength();
	if (length != (spub_key_length + epub_key_length)) {
		// Wrong data length
		return false;
	}
	shared_.New(dh2_.AgreedValueLength());
	const byte* buf = (const byte*)buffer;
	if (!dh2_.Agree(shared_, spriv_key_, epriv_key_, buf, buf + spub_key_length)) {
		// Failed to reach shared secret
		return false;
	}
	return true;
}

When client process it, client sends to server new data with 256 bytes.Then they have common keys.Client process common key and encryption starts.But i couldn't translate it to c# exactly.

Here is my code, i used bouncy castle for diffie hellman class.

Code:
  public void FUDiffieHellman(byte[] buffer)
        {
        public static string Phex = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371";
        public static string Ghex = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5";
        public static string Qhex = "F518AA8781A8DF278ABA4E7D64B7CB9D49462353";

            BigInteger P = new BigInteger(Phex, 16);
            BigInteger G = new BigInteger(Ghex, 16);
            BigInteger Q = new BigInteger(Qhex, 16);

            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH");

            DHParameters dhParams = new DHParameters(P, G, Q, 0);



            KeyGenerationParameters kgp = new DHKeyGenerationParameters(new SecureRandom(), dhParams);
            keyGen.Init(kgp);

            AsymmetricCipherKeyPair clentKeypeyir = keyGen.GenerateKeyPair();
            IBasicAgreement clentEgri = AgreementUtilities.GetBasicAgreement("DH");
            clentEgri.Init(clentKeypeyir.Private);

            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(clentKeypeyir.Public);
            byte[] publicKeyData = publicKeyInfo.GetDerEncoded();


            AsymmetricKeyParameter ReceivedKey = PublicKeyFactory.CreateKey(buffer);

            BigInteger commonBigInteger = clentEgri.CalculateAgreement(ReceivedKey);

            // ??
        }
Thanks in anyways.
04/09/2018 18:39 matalaj#2
How to generate new integrer ? ex 0xF518AA8781A8DF278ABA4E7D64B7CB9D49462353