# VBForums UtilityBank > UtilityBank - Components >  VB6 - EChat

## couttsj

Attached is a chat program called EChat, which is short for Encrypted Chat. It actually consists of 3 programs; the Client program, the Service program, and a Control program to maintain the Service program. Why is it any different from other chat programs? The answer is Security.

To activate the Client program requires a password. The password is not stored. What is stored in the registry is a simple numeric sum check. I could have stored it encrypted, but that would have meant storing a key, and key storage is a security risk in any encryption system. 

The Client connects to the server and sends the UserID and the Public Key from a self generated ECC (Elliptical Curve Cryptography) key pair. The server verifies the UserID and generates it's own Public/Private ECC key pair. It uses it's own Private Key, and the Public Key from the Client to generate a Shared Secret. It then sends it's Public Key back to the Client. 

The Client had previously hashed the Password that was input to activate the program. It then generates the Shared Secret using the Public Key from the Server and it's own Private Key. It uses that Shared Secret to encrypt the hashed Password and sends it back to the Server.

The Server uses the Shared Secret to decrypt and verify the Password hash. When the Server was started, it generated a 256 bit Random Key. It now encrypts the Random Key with the Shared Secret, and sends it back to the Client. All connected Clients are sent a message that the new Client has joined the conversation, and the Client list is updated. All subsequent conversation data is encrypted/decrypted with the Random Key. The Server does not decrypt the messages, it simply passes the encrypted data on to the participants. To view the decrypted messages would require being one of the participants.

The above programs require my encryption library file available here:
_-Linked Removed by Moderator-_
It can be stored in the executable directory or in the Windows System (\Windows\System32 or \Windows\SysWOW64) directory.

The Server program can operate as a Desktop application or as a Service, but it does require the Microsoft NT Service Control. Normally, the UserID and hashed Password would be maintained in a database on a Secure Server. But not everyone has access to a Secure Server. In addition, Access databases do not easily store binary information that is not a recognized variable type. So I chose to develop my own binary based database using binary file access. A UserID is not encrypted information, so it can be passed on using insecure email. But a Password should never be passed using insecure communication. So what I suggest is to manually add the UserID and a blank Password to the database, and then have the new Client attempt to connect. The hashed password can then be taken from the log file and added to the User database. The Server end never has knowledge of the actual Password, because a Hash is like one-way encryption.

Operating as a service requires different settings and directories as compared to operating as a desktop application. The reason for this is that a service operates as part of the system in session zero, whereas a desktop application operates in session one or better. Each one has it's own set of permissions as far as directories and registry are concerned. I suggest that the desktop application be compiled as "EChatS.exe". Change the "IsService" flag to true and compile the service as "EChatSvc.exe". The desktop application will require a sub directory called "Logs" in the directory where the executable is located, whereas the service will require a sub directory called "EChat" in "\Windows\System32\Logfiles". In this particular case, it doesn't matter if it is a 32 or 64 bit system. For both programs, the User Database is located in the "ProgramData\EChat" directory. If it doesn't exist, the program will create it and copy a blank database (Users.db.org) into that directory as Users.db. This database actually includes one UserID called "Admin" and a blank password.

J.A. Coutts

----------


## couttsj

I ran into a problem with editing of the User database, and updated the attachments. The only part of the attachments that has changed is the prjInterface (EChatCtrl).

J.A. Coutts

----------


## dreammanor

When I open EChatSvc.vbp, there is a prompt: NTSVC.ocx could not be loaded ...

I found such a useful message on the Internet:

NT Service in VB6 Without NTSvc.ocx
http://www.freevbcode.com/ShowCode.asp?ID=4317

----------


## DEXWERX

> To activate the Client program requires a password. The password is not stored. What is stored in the registry is a simple numeric sum check. I could have stored it encrypted, but that would have meant storing a key, and key storage is a security risk in any encryption system.


Why store an easily brute forced crc, when you could store a salted and 1-way crypto hashed pw + salt?

https://en.wikipedia.org/wiki/Crypto..._hash_function
https://en.wikipedia.org/wiki/Salt_(cryptography)



also you might wanna remove the dll from your download before the mods do.

----------


## dilettante

We've been told we can't provide links to pages offering compiled code downloads, much less hot links to such compiled code.

Hmm, that site seems to be tracking clients too.  If nothing else you might want to use Tor Browser to visit it.

----------


## couttsj

> Why store an easily brute forced crc, when you could store a salted and 1-way crypto hashed pw + salt?
> also you might wanna remove the dll from your download before the mods do.


It is salted, with a minimum character length of 16, plus a character offset. And there is no DLL in the downloads.

J.A. Coutts

----------


## couttsj

> When I open EChatSvc.vbp, there is a prompt: NTSVC.ocx could not be loaded ...


A simple internet search will find the control. I got mine from andreavb.com.

J.A> Coutts

----------


## DEXWERX

> It is salted, with a minimum character length of 16, plus a character offset. And there is no DLL in the downloads.
> 
> J.A. Coutts


A non-random salt, i.e. no entropy... 

That's actually not even that big of a deal, compared to the fact that you've taken your complex password requirements and literally converted it to the equivalent of 4 characters... 

How many combinations of 4 characters do you think it would take to come up with the same crc?
How long do you think it would take to brute force? hint: less than 30seconds.

https://en.wikipedia.org/wiki/Mallea...ryptography%29

NOTE: I may be overly harsh though, Cyber security is tough - even if you follow industry standards there are lots of ways to shoot yourself in the foot.
This is just an example VB app, and I am paid to maintain critical cyber infrastructure.


_and there is definitely a jCrypt.dll _in_ EChat.zip_

Personally I would never trust an encryption dll without source that's not from an expert security vendor... 
Even if you got it from MS or Symantec... without the source you're taking a calculated risk.

----------


## couttsj

> _and there is definitely a jCrypt.dll _in_ EChat.zip_
> [/COLOR]


If I did indeed upload EChat.zip, it was done in error and I apologize. It was supposed to be EChatC.zip, and the moderator was justified in removing it.

J.A. Coutts

----------


## couttsj

> That's actually not even that big of a deal, compared to the fact that you've taken your complex password requirements and literally converted it to the equivalent of 4 characters... 
> 
> How many combinations of 4 characters do you think it would take to come up with the same crc?
> How long do you think it would take to brute force? hint: less than 30seconds.


I agree that it seems a bit crude, but I know of no way to fully protect an application if the hacker has access to the computer. Given enough time and resources, any stored item can be hacked, including stored keys. One of the easiest ways to get a password is to install a keylogger. I am not sure where the 4 characters came from, but the sum check is a long variable (-2,147,483,648 to 2,147,483,647), and I padded the source with a pre-amble and a post-amble to make sure it had sufficient size. The added advantage of using the sum check is that there are multiple combinations of characters that can arrive at the same sum check number, so the hacker would have to try and connect with each one. Each bad password attempt is logged, allowing the administrator to detect hack attempts.

The password is never stored in memory or on the disk. It is hashed and then encrypted before being sent to the server.

J.A. Coutts

----------


## DEXWERX

> I agree that it seems a bit crude, but I know of no way to fully protect an application if the hacker has access to the computer. Given enough time and resources, any stored item can be hacked, including stored keys. One of the easiest ways to get a password is to install a keylogger. I am not sure where the 4 characters came from, but the sum check is a long variable (-2,147,483,648 to 2,147,483,647), and I padded the source with a pre-amble and a post-amble to make sure it had sufficient size. The added advantage of using the sum check is that there are multiple combinations of characters that can arrive at the same sum check number, so the hacker would have to try and connect with each one. Each bad password attempt is logged, allowing the administrator to detect hack attempts.
> 
> The password is never stored in memory or on the disk. It is hashed and then encrypted before being sent to the server.
> 
> J.A. Coutts


I completely agree - you can't fully protect an application, once a hacker has access to the computer. 

That said - the recommended industry standard is to store a 1 way hash (SHA-512) with a random salt, and not store the password itself.
The 1 way hash is effectively the same functionality as your crc (without the obvious vulnerability detailed below), and the random salt mitigates the use of a precomputed hash/rainbow table attack. Implementing this - instead of a crc, would be less code than your crc, and be exponentially more secure.


The problem with storing a crc - is that it is easily "cracked". I wouldn't even call it a crack since it's so simple to circumvent. A CRC is so malleable it can be spoofed by modifying as few characters as the size of the crc itself. Your 4 byte crc check, can literally be circumvented with a brute forced 4 character password.
I'm not talking about the actual password mind you - just one that produces the same CRC. 

_Who cares what the complex password is - if all you need to do is guess 4 characters that produce the same CRC._

*note:* This is why no one even uses CRC for file verification anymore. Even MD5 is out of vogue because it's technically possible to compute a collision.

----------


## couttsj

> That said - the recommended industry standard is to store a 1 way hash (SHA-512) with a random salt, and not store the password itself.


Thank you for the explanation. One quick question. I assume that what you meant by random is random for each installation, and not for each access or application. Can one use something like the CPU serial number?

J.A. Coutts

----------


## DEXWERX

> Thank you for the explanation. One quick question. I assume that what you meant by random is random for each installation, and not for each access or application. Can one use something like the CPU serial number?
> 
> J.A. Coutts


yes, typically the salt is set only when a new password is stored, not each access.
For the salt, you can use any cryptographic pseudo random number generator like CryptGenRandom / RtlGenRandom. 

You could use the CPU serial as a salt, or even as a seed instead of something random, but I would think a simple random number is more reliable than trying to get the serial. 

(RtlGenRandom already uses the system environment as part of it's entropy.)

----------


## couttsj

When DEXWERX pointed out how insecure a hashed password is, I started investigating. I found a Web site (crackstation.net) that took it even further. A hash can be a useful tool, but passwords are so short that they are easily cracked. They compiled a large indexed database of password hashes using variations of dictionary words, and this web site allows you to test any hash. For example, the 256 bit hash of "password" is:

5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8

It took all of 2 seconds for the web site to figure out that it was an sha256 hash of "password". When I reversed the characters:

8D2451D127FE11A26DDBBAA6D0D3063772926CD8F65E0D15174082AD898488E5

It took about the same amount of time for the site to be unable to find the answer. The same situation exists for salted password hashes. The page "crackstation.net/hashing-security.htm" explains in depth the right and wrong ways of implementing password protection.

But what the page only touches on is the vulnerability of the user database itself. To make the stored hash on the server different from the password hash the client uses, the server must store a unique salt for each user. Should the hacker gain access to the user database complete with unique salts, it is only a matter of time until the hashed passwords are figured out. A hashed password from the client is no different from the password itself. It can be used to connect to the server directly without knowing the real password. The current EChat program passes the password hash encrypted, but the user database stores the hashed passwords directly. When (not if), a hacker gains access to the database, he/she has all the user hashed passwords, and can use these to gain access to EChat. I need to find a better way of storing the hashed passwords.

J.A. Coutts

----------


## dreammanor

Hi couttsj, have you found a better way to store the hashed passwords?

----------


## PlausiblyDamp

> But what the page only touches on is the vulnerability of the user database itself. To make the stored hash on the server different from the password hash the client uses, the server must store a unique salt for each user. Should the hacker gain access to the user database complete with unique salts, it is only a matter of time until the hashed passwords are figured out. A hashed password from the client is no different from the password itself. It can be used to connect to the server directly without knowing the real password. The current EChat program passes the password hash encrypted, but the user database stores the hashed passwords directly. When (not if), a hacker gains access to the database, he/she has all the user hashed passwords, and can use these to gain access to EChat. I need to find a better way of storing the hashed passwords.
> J.A. Coutts


If someone has access to the database itself, then getting access to the hashed passwords and the associated salt value is the least of your problems; they have access to your entire database so being able to fake a login to gain access to data is now an irrelevant step. Hashes of simple or common passwords without salting are always going to fall foul of dictionary attacks and shouldn't be considered secure. The database needs to be properly secured to prevent people gaining access directly.

If you are sending hashed passwords from the client to the server over a connection that isn't encrypted then you aren't really making things secure - as you said the hash is the password to all intents and purposes. Anytime you are sending confidential information between a client and a server it should be encrypted, setting up SSL on most web servers is pretty trivial these days and should always be used in this kind of situation. If you are dealing with Tcp sockets directly then it might be a bit more difficult on VB6 compared to .Net but it really should still be implemented.

----------


## couttsj

> Hi couttsj, have you found a better way to store the hashed passwords?


Yes I have. As some have alluded to, a simple hash of a password is too easy to get around. The solution some have mentioned is to salt the hash. That does make it more difficult, but it also means that you now have to store the salt as well. Anything that is stored becomes a security risk. What I came up with is to randomly shuffle the hash bytes and then store it. It is not a true random shuffle, because you can unshuffle the bytes based on a key. That key can be anything the server has access to, as only the server needs to use it. The password hash is always transmitted encrypted.

J.A. Coutts

See:
http://www.vbforums.com/showthread.p...6Yates-shuffle

----------


## dreammanor

Thanks, I'll try it.

----------

