Register for your free account! | Forgot your password?

You last visited: Today at 23:45

  • Please register to post and access all features, it's quick, easy and FREE!


[C++] DHKey Exchange in 5672

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jul 2009
Posts: 487
Received Thanks: 178
[C++] DHKey Exchange in 5672

Hello Epvpers!
Here I am looking for help again! I've been trying to write an source in C++ in the last months, took me a lot since I'm trying to don't take anything from the sources out there and writing a socket system was the worst part xD
Well, first of all, the problem. I'm pretty sure that the problem is on that part of the code. Why? Because I sent the DHKey Challenge, the client is sending it back and I'm able to read it, so the Cast5 Cipher is working properly. But I'm not being able to set the client key to start the game packet exchange.
I've got success upgrading my C# source, I tried it to make sure that what I wrote was correct and it worked on the C# source. The C# Hex thing I've got from somewhere, but the point is that it work.
I think that the problem may be in the Hex thing, since the md5 is from the OpenSSL dll and it's the same for everything.

Thank you if you at least read it and if anybody could give me a light, It would be great.



pintinho12 is offline  
Old 12/31/2017, 18:46   #2
 
elite*gold: 12
Join Date: Jul 2011
Posts: 7,005
Received Thanks: 3,357
Here's an additional reference from a private branch of Chimera ...

Code:
// Package for the diffie-hellman key exchange and its alternatives. The
// Conquer Online game client uses DH to establish a shared key for CAST-5
// over an insecure communications channel. This does not assist in reducing
// active attacks, and thus adds very little security to the server. Only
// helps reduce passive attacks such as eavesdropping. This package has been
// modified for interoperability with the Conquer Online game client.
package dh

import (
    "bytes"
    "crypto/rand"
    "crypto/md5"
    "encoding/hex"
    "math/big"
)

const (
    Generator = "05"
    Modulus   = "E7A69EBDF105F2A6BBDEAD7E798F76A209AD73FB466431E2E7352ED2" +
                "62F8C558F10BEFEA977DE9E21DCEE9B04D245F300ECCBBA03E726305" +
                "56D011023F9E857F"
)

// Exchange defines DH protocol for the server. For documentation purposes,
// the server will be Alice in the exchange protocol. Some variables are 
// captitalized incorrectly to be exported.
type Server struct {
    P *big.Int // Public prime modulus, known to all parties.
    G *big.Int // Public prime generator, known to both parties.
    A *big.Int // Alice's public key, known to both parties
    a *big.Int // Alice's private key.
    B *big.Int // Bob's public key (the client's public key).
}

// NewServer accepts a prime modulus and generator for initializing DH.
func NewServer(p, g string) *Server {
    
    server := new(Server)
    server.P = new(big.Int)
    server.G = new(big.Int)
    server.P.SetString(p, 16)
    server.G.SetString(g, 16)
    return server
}

// Request starts the exchange and generates the server's public key to be 
// sent over the unsecure communications channel. Returns the public key as
// a hexadecimal string to be sent to the game client.
func (server *Server) Request() (string, error) {
    
    var err error
    server.a, err = rand.Prime(rand.Reader, 256)
    if err != nil { return "", err }
    server.A = server.G.Exp(server.G, server.a, server.P)
    return server.A.Text(16), nil
}

// Response to be processed from the game client. The response contains the
// client's public key. From this key, the shared key can be computed between
// the parties. Returns the shared key.
func (server *Server) Response(clientkey string) []byte {
    
    server.B = new(big.Int)
    server.B.SetString(clientkey, 16)
    sharedkey := server.B.Exp(server.B, server.a, server.P)
    
    // The shared key is trimmed for some reason in TQ's version.
    sharedkeybuf := sharedkey.Bytes()
    sharedkeylen := len(sharedkeybuf)
    trimmedkeylen := bytes.IndexByte(sharedkeybuf, 0)
    if trimmedkeylen == -1 { trimmedkeylen = sharedkeylen }
    trimmedkey := sharedkeybuf[:trimmedkeylen]
    
    // TQ Digital hash modification to the shared key.
    hash := md5.New()
    hash.Write(trimmedkey)
    left := hex.EncodeToString(hash.Sum(nil))
    right := left + left
    
    hash = md5.New()
    hash.Write([]byte(right))
    right = hex.EncodeToString(hash.Sum(nil))
    return []byte(left + right)
}


Spirited is offline  
Thanks
1 User
Old 12/31/2017, 21:36   #3

 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,394
Received Thanks: 1,055
I see multiple errors or possible improvements in your code.

First, if your pointer cannot be NULL (e.g. cipher), you can use references instead of pointers. You're usage of std::string is not optimal. You could reserve the capacity instead of forcing the object to reallocate its internal buffer.

The function Hex has multiple issues. First, you have a memory leak. You allocate memory on the heap for c (it will be implicitly casted to std::string on return), but c will remain allocated when you exit the function. You can improve your code by using memset instead of ZeroMemory, the later being only available on MSVC. In your loop, you compare a int to a size_t. If len is larger than an int (possible on 64 bits platforms), you can loop and get negative indexes when the integer will overlap. Other thing, a char not specified to be signed or unsigned, but most of the time, it is signed. A byte (in C#) is unsigned, as such, either use 'unsigned char', or if you want specifically a 8-bit integer, you should use uint8_t. In C++, basic types do not have fixed sizes. Also, I see a major problem with you using a char. If signed, when you will shift the value by 4 bits, the shift operator will keep the sign.

Have you check that the resulting strings are identical using your C++/C# implementations? For the same data, they should. You can easily compare both and find which part is wrong.
CptSky is offline  
Thanks
1 User
Old 01/01/2018, 01:13   #4
 
elite*gold: 0
Join Date: Jul 2009
Posts: 487
Received Thanks: 178
Quote:
Originally Posted by CptSky View Post
I see multiple errors or possible improvements in your code.

First, if your pointer cannot be NULL (e.g. cipher), you can use references instead of pointers. You're usage of std::string is not optimal. You could reserve the capacity instead of forcing the object to reallocate its internal buffer.

The function Hex has multiple issues. First, you have a memory leak. You allocate memory on the heap for c (it will be implicitly casted to std::string on return), but c will remain allocated when you exit the function. You can improve your code by using memset instead of ZeroMemory, the later being only available on MSVC. In your loop, you compare a int to a size_t. If len is larger than an int (possible on 64 bits platforms), you can loop and get negative indexes when the integer will overlap. Other thing, a char not specified to be signed or unsigned, but most of the time, it is signed. A byte (in C#) is unsigned, as such, either use 'unsigned char', or if you want specifically a 8-bit integer, you should use uint8_t. In C++, basic types do not have fixed sizes. Also, I see a major problem with you using a char. If signed, when you will shift the value by 4 bits, the shift operator will keep the sign.

Have you check that the resulting strings are identical using your C++/C# implementations? For the same data, they should. You can easily compare both and find which part is wrong.
I tested the Hex function and both implementations when receiving the same data return the same value. So, I noticed that the the DHKey (Which I got from cops) returns an string with the bytes (string parsed). I'll now try to convert it to a byte array.

Thank you for the tips.
Also ty Spirited, your code helped me finding out something pretty obvious xD and also something I didn't noticed before. I'll edit here after i commit the changes.

Seryiously, I should kill myself.
The md5 function I built already encoded the chars into the byte strings. I was doing it twice, that's why it was wrong. The Hex function wasn't even needed! Now it's working.
@Spirited your code your code helped me on the array trim and to figure out that my response was the bytes as string xD I needed the array.
@CptSky there was a memory problem on the hex function I fixed it XD thank you even if I wont use that anymore, I should pay more atention.
Thanks for the help.



Topic can be closed.
pintinho12 is offline  
Reply



« [HELP] Adding Monster | little problem »

Similar Threads
is the DHKey exchange changed ?
09/13/2016 - CO2 Main - Discussions / Questions - 2 Replies
Hello, i'm trying to decrypt the DHKey but after i get the packet i can't read the IV's or the public key i have tried "Pro4Never" algorithm but the problem is this line int JunkLength = BR.ReadInt32(); when print it out i get a very big value...
Proxy Server DHKey Exchance
03/19/2013 - CO2 Programming - 7 Replies
Hello, epvp how are you guys??? i finally finished my proxy(not bot for now) i maked the client merged (auth and game) auth encryption is easy cause it doesnt need a dhkey but my problem is in game encryption i have lastest encryption...
[Important]Needed Update For DHKey For ProxyParadise .
09/15/2012 - CO2 Main - Discussions / Questions - 11 Replies
Hello Guys, Am Here Today To Ask Any Body To Upgrade DH-Key and Add MD5 To Proxy Paradise Pro4Never's Proxy To work on The Latest Co Client That's Will Be Very Useful , I Have Tried Many Times But I Couldn't When I go For Log In It Disconnects...



All times are GMT +2. The time now is 23:45.


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Abuse
Copyright ©2018 elitepvpers All Rights Reserved.