Simple password authentication in TCP client server architecture - tcp

Good morning everyone.
I've been reading (most of it here in stack overflow) about how to make a secure password authentication (hashing n times, using salt, etc) but I'm in doubt of how I'll actually implement it in my TCP client-server architecture.
I have already implemented and tested the methods I need (using jasypt digester), but my doubt is where to do the hashing and its verification.
As for what I read, a good practice is to avoid transmitting the password. In this case, the server would send the hashed password and the client would test it with the one entered by the user. After that I have to tell the server if the authentication was successful or not. Ok, this won't work becouse anyone who connect to the socket the server is reading and send a "authentication ok" will be logged on.
The other option is to send the password's has to the server. In this case I don't see any actual benefit from hashing, since the "attacker" will have to just send the same hash to authenticate.
Probably I'm not getting some details, so, can anyone give me a light on this?

The short answer to your question is definitely on the side that permanently stores the hashes of the passwords.
The long answer: hashing passwords only allows to prevent an attacker with read-only access to your passwords storage (e.g. database) from escalating to higher power levels and to prevent you knowing the actual secret password, because lots of users use same pass across multiple services (good description here and here). That is why you need to do the validation on the storage side (because otherwize, as you've mentioned, attacker would just send "validation ok" message and that's it).
However if you want to implement truly secure connection, simple passwords hashing is not enough (as you've also mentioned, attacker could sniff TCP traffic and reveal the hash). For this purpose you need to establish a secure connection, which is much harder than just hashing password (in web world a page where you enter your pass should always be served over HTTPS). The SSL/TLS should be used for this, however these protocols lie on top of TCP, so you might need another solution (in common, you need to have a trusted certificate source, need to validate the server cert, need to generate a common symmetric encryption key and then encrypt all data you send). After you've established secure encrypted connection, encrypted data is useless to sniff, the attacker would never know the hash of the password.

Related

Decrypting UDP Packets from Game with Known Key

I'm trying to decrypt UDP packets for a multiplayer video game. When loading into a game session, a DTLS handshake occurs where, in Wireshark, I usually see the Client and Server agree on ChaCha20 Poly1305 encryption. The game actually live logs a "key" in a log file, which is 32 bytes long hex-coded, along with an HMAC and IV. At this point I'm not sure what to do. I tried decrypting individual messages in Python with some cryptography libraries but I realized that might be silly upon learning DTLS, or at least TLS packets, cannot be decrypted independently. I know I can possibly have Wireshark point to a file or add a key to live decrypt something, but have not had luck doing so. I started this process from basically no knowledge on internet security protocols or cryptography and have learned a lot but am at a standstill, and just want to make sure I'm not far off-base here.
Wireshark screenshot of handshake
It depends on what the game is actually writing to the file. Wireshark has support for decrypting TLS/DTLS using the RSA private key, the premaster secret or master secret. If the log file contains the premaster or master secret, then you should be able to shoe-horn it into wireshark, and decrypt the stream from there.
If it isn't, then you'll need to work out what it actually is first, and then it's a bit more of a manual job to get at the data.

Do servers remember clients and user agents?

Do the big guys (Google, Microsoft, etc...) remember all HTTP clients and more importantly, the User-Agents that connected to them?
If so, should you implement this as a startup? (make your server remember the clients)
I'm not asking for advice, only for practicality or if there's some protocol somewhere that requires it. Like what's the standard, not your opinion.
The standard is: if there is data you need then you collect and store it. If you don't need the data then don't bother.
That information is in the request header sent by the browser. Anything the browser sends to the server can be collected, processed, stored, etc...
There is no protocol that requires it and you do not have to store this information.

Is SSL appropriate for sending secure contents?

I am using mailR to send emails through R. This is my code
send.mail(from = [from],
to = [to],
subject = "msg",
body = "contents",
html = FALSE,
inline = FALSE,
authenticate = TRUE,
smtp = list(host.name = "smtp.gmail.com",
port = 465,
user.name = [username],
passwd = [password],
ssl = TRUE),
attach.files = "/home/User/outputlog.txt",
send = TRUE)
I am sending sensitive info in the attachment. I am sending it through SSL.
I read this post about how secure SSL is and it looks pretty secure.
Does this message get encrypted in transit?
In theory, yes (for some definition of "transit"), but in practice for "Does this message get encrypted in transit?" the answer is maybe. In short, just ssl = True or equivalent put somewhere does almost not guarantee anything really, for all the reasons explained below.
Hence you are probably not going to like the following detailed response, as it shows basically that nothing is simple and that you have no 100% guarantee even if you do everything right and you have A LOT of things to do right.
Also TLS is the real true name of the feature you are using, SSL is dead since 20 days now, yes everyone use the old name, but that does not make this usage right nevertheless.
First, and very important, TLS provides various guarantees, among which confidentiality (the content is encrypted while in transit), but also authentication which is in your case far more important, and for the following reasons.
You need to make sure that smtp.gmail.com is resolved correctly, otherwise if your server uses lying resolvers, and is inside an hostile network that rewrites the DNS queries or responses, then you can send an encrypted content... to another party than the real "smtp.gmail.com" which makes the content not confidential anymore because you are sending it to a stranger or an active attacker.
To solve that, you need basically DNSSEC, if you are serious.
No, and contrary to what a lot of people seem to believe and convey, TLS alone or even DOH - DNS over HTTPS - do not solve that point.
Why? Because of the following that is not purely theoretical since it
happened recently (https://www.bleepingcomputer.com/news/security/hacker-hijacks-dns-server-of-myetherwallet-to-steal-160-000/), even if it was in the WWW world and not the email, the scenario can be the same:
you manage to grab the IP addresses tied to the name contacted (this can be done by a BGP hijack and it happens, for misconfigurations, "policy" reasons, or active attacks, all the time)
now that you control all communications, you put whatever server you need at the end of it
you contact any CA delivering DV certificates, including those purely automated
since the name now basically resolve to an IP you control, the web (or even DNS) validation that a CA can do will succeed and the CA will give you a certificate for this name (which may continue to work even after the end of the BGP hijack because CAs may not be quick to revoke certificates, and clients may not properly check for that).
hence any TLS stack accepting this CA will happily accept this certificate and your client will send securely content with TLS... to another target than the intended one, hence 0 real security.
In fact, as the link above shows, attackers do not even need to be so smart: even a self signed certificate or an hostname mismatch may go through because users will not care and/or library will have improper default behavior and/or programmer using the library will not use it properly (see this fascinating, albeit a tad old now, paper showing the very sad state of many "SSL" toolkits with incorrect default behavior, confusing APIs and various errors making invalid use of it far more probably than proper sane TLS operations: https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf)
Proper TLS use does not make DNSSEC irrelevant. Both targets and protects against different attacks. You need both to be more secure than just with one, and any of the two (properly used) does not replace the other. Never has and never will.
Now even if the resolution is correct, someone may have hijacked (thanks to BGP) the IP address. Then, again, you are sending to some host some encrypted content except that you do not really authenticate who is this host, so it can be anyone if an attacker managed to hijack IP addresses of smtp.gmail.com (it does not need to do it globally, just locally, "around" where your code execute).
This is where the very important TLS property of authentication kicks in.
This is typically done through X.509 certificates (which will be called - incorrectly - SSL certificates everywhere). Each end of the communication authenticate the other one by looking at the certificate it presented: either it recognizes this certificate as special, or it recognizes the issuing authority of this certificate as trusted.
So you do not just need to connect with TLS on smtp.gmail.com you also need to double check that the certificate then presented:
is for smtp.gmail.com (and not any other name), taking into account wildcards
is issued by a certificate authority you trust
All of this is normally handled by the TLS library you use except that in many cases you need at least to explicitly enable this behaviour (verification) and you need, if you want to be extra sure, to decide clearly with CAs you trust. Otherwise, too many attacks happen as can be seen in the past by rogue, incompetent or other adjectives CAs that issued certificates where they should not (and yes noone is safe against that, even Google and Microsoft got in the past mis-issued certificates with potential devastating consequences).
Now you have another problem more specific to SMTP and SMTP over TLS: the server typically advertises it does TLS and the client seeing this then can start the TLS exchange. Then all is fine (baring all the above).
But in the path between the SMTP server and you someone can rewrite the first part (which is in clear) in order to remove the information that this SMTP server speaks TLS. Then the client will not see TLS and will continue (depending on how it is developed, of course to be secure in such cases the client should abort the communication), then speaking in clear. This is called a downgrade attack. See this detailed explanation for example: https://elie.net/blog/understanding-how-tls-downgrade-attacks-prevent-email-encryption/
As Steffen points out, based on the port you are using this above issue of SMTP STARTTLS and hence the possible downgrade does not exist, because this is for port 25 which you are not using. However I prefer to still warn users about this case because it may not be well known and downgrade attacks are often both hard to detect and hard to defend against (all of this because protocols used nowadays were designed at a time where there was no need to even think about defending one against a malicious actor on the path)
Then of course you have the problem of the TLS version you use, and its parameters. The standard is now TLS version 1.3 but this is still slowly being deployed everywhere. You will find many TLS servers only knowing about 1.2
This can be good enough, if some precautions are taken. But you will also find old stuff speaking TLS 1.1, 1.0 or even worse (that is SSL 3). A secure client code should refuse to continue exchanging packets if it was not able to secure at least a TLS 1.2 connection.
Again this is normally all handled by your "SSL" library, but again you have to check for that, enable the proper settings, etc.
You have also a similar downgrade attack problem: without care, a server first advertise what it offers, in clear, and hence an attacker could modify this to remove the "highest" secure versions to force the client to use a lower versions that has more attacks (there are various attacks against TLS 1.0 and 1.1).
There are solutions, specially in TLS 1.3 and 1.2 (https://www.rfc-editor.org/rfc/rfc7633 : "The purpose of the TLS feature extension is to prevent downgrade
attacks that are not otherwise prevented by the TLS protocol.")
Aside and contrary to Steffen's opinion I do no think that TLS downgrade attacks are purely theoretical. Some examples:
(from 2014): https://p16.praetorian.com/blog/man-in-the-middle-tls-ssl-protocol-downgrade-attack (mostly because web browsers are eager to connect no matter what so typically if an attempt with highest settings fail they will fallback to lower versions until finding a case where the connection happens)
https://www.rfc-editor.org/rfc/rfc7507 specifically offers a protection, stating that: "All unnecessary protocol downgrades are undesirable (e.g., from TLS
1.2 to TLS 1.1, if both the client and the server actually do support
TLS 1.2); they can be particularly harmful when the result is loss of
the TLS extension feature by downgrading to SSL 3.0. This document
defines an SCSV that can be employed to prevent unintended protocol
downgrades between clients and servers that comply with this document
by having the client indicate that the current connection attempt is
merely a fallback and by having the server return a fatal alert if it
detects an inappropriate fallback."
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/february/downgrade-attack-on-tls-1.3-and-vulnerabilities-in-major-tls-libraries/ discusses not less than 5 CVEs in 2018 that allows TLS attacks: " Two ways exist to attack TLS 1.3. In each attack, the server needs to support an older version of the protocol as well. [..] The second one relies on the fact that both peers support an older version of TLS with a cipher suite supporting an RSA key exchange." and "This prowess is achieved because of the only known downgrade attack on TLS 1.3." and "Besides protocol downgrades, other techniques exist to force browser clients to fallback onto older TLS versions: network glitches, a spoofed TCP RST packet, a lack of response, etc. (see POODLE)".
Even if you are using a correct version, you need to make sure to use correct algorithms, key sizes, etc. Sometimes some server/library enable a "NULL" encryption algorithm, which means in fact no encryption. Silly of course, but that exists, and this is a simple case, there are far more complicated ones.
This other post from Steffen: https://serverfault.com/a/696502/396475 summarizes and touches the various above points, and gives another views on what is most important (we disagree on this, but he answered here as well so anyone is free to take both views into account and make their own opinion).
Hence MTA-STS instead of SMTP STARTTLS, https://www.rfc-editor.org/rfc/rfc8461 with this clear abstract:
SMTP MTA Strict Transport Security (MTA-STS) is a mechanism
enabling mail service providers (SPs) to declare their ability to
receive Transport Layer Security (TLS) secure SMTP connections and
to specify whether sending SMTP servers should refuse to deliver to
MX hosts that do not offer TLS with a trusted server certificate.
Hence you will need to make sure that the host you send your email too does use that feature, and that your client is correctly programmed to handle it.
Again, probably done inside your "SSL Library" but this clearly show you need specific bit in it for SMTP, and you need to contact a webserver to retrieve the remote end SMTP policies, and you need also to do DNS requests, which gets back to you on one of the earlier point about if you trust your resolver or not and if records are protected with DNSSEC.
And with all the above, which already covers many areas and is really hard to do correctly, there are still many other points to cover...
The transit is safe, let us assume. But then how does the content gets retrieved? You may say it is not your problem anymore. Maybe. Maybe not. Do you want to be liable for that? Which means that you should maybe also encrypt the attachment itself, this is in addition (not in replacement) of the transport being secured.
The default mechanisms to secure email contents either use OpenPGP (has a more geek touch to it), or S/MIME (has a more corporate touch to it). This works for everything. Then you have specific solutions depending on the document (but this does not solve the problem of securing the body of the email), like PDF documents can be protected by a password (warning: this has been cracked in the past).
I am sending sensitive info
This is then probably covered by some contract or some norms, depending on your area of business. You may want to dig deeper into those to see exactly what are the requirements forced upon you so that you are not liable for some problems, if you secured everything else correctly.
First, even if SSL/TLS is properly used when delivering the mail from the client it only protects the first step of delivery, i.e. the delivery to the first MTA (mail transfer agent). But mail gets delivered in multiple steps over multiple MTA and then it gets finally retrieved from the client from the last mail server.
Each of these hops (MTA) has access to the plain mail, i.e. TLS is only between hops but not end-to-end between sender and recipient. Additionally the initial client has no control how one hop will deliver the mail to the next hop. This might be also done with TLS but it might be done in plain. Or it might be done with TLS where no certificates get properly checked which means that it is open to MITM attacks. Apart from that each MTA in the delivery chain has access to the mail in plain text.
In addition to that the delivery to the initial MTA might already have problems. While you use port 465 with smtps (TLS from start instead upgrade from plain using a STARTTLS command) the certificate of the server need to be properly checked. I've had a look at the source code of mailR to check how this is done: mailR essentially is using Email from Apache Commons. And while mailR uses setSSL to enable TLS from start it does not use setSSLCheckServerIdentity to enable proper checking of the certificate. Since the default is to not properly check the certificate already the connection to the initial MTA is vulnerable to man in the middle attacks.
In summary: the delivery is not secure, both due to how mail delivery works (hop-by-hop and not end-to-end) and how mailR uses TLS. To have proper end-to-end security you'll to encrypt the mail itself and not just the delivery. PGP and S/MIME are the established methods for this.
For more see also How SSL works in SMTP? and How secure is e-mail landscape right now?.

Are hashes and MACs vulnerable to bit-flipping attacks?

Suppose there is an encrypted communication between A and B, through an unsecure medium, such that A and B shared a secret key with DH protocol.
If A sends an encrypted message and the hash/MAC/HMAC of this message to B, wouldn't it be easy for an eavesdropper to just intercept the hash/MAC/HMAC, change some bits in it, and send it to B?
B wouldn't be able to check the integrity of all messages sent by A and thus will destroy them everytime he gets a message from A, right?
B will then become non available ???
Thank you
The process you describe is just a very specific form of corrupting the data. If an attacker can corrupt the data, then of course the attacker can prevent A from speaking to B. The attacker could just drop the packets on the ground. That would also prevent A from speaking to B.
Any data corruption, not just modifying the HMAC, will cause this same situation. If I modify the authenticated stream, then the (unmodified) HMAC won't match and it will be discarded.
The point of an HMAC is to ensure integrity. It has nothing to do with availability. Any Man-in-the-Middle can always trivially destroy availability in any system as long as the connection goes through them. (If they can't, they're not a MitM.)

Diffie-Hellman in place of SSL?

Can a Diffie-Hellman key exchange algorithm be used to encrypt client-server communication on a web-page in place of SSL? If it can, what are the disadvantages (i.e. why does the standard use SSL which requires a certificate authority)? My understanding is that Diffie-Hellman can be used to secretly establish a shared key which then can be use to encrypt any further communication.
The two aren't really comparable. DH is a key-exchange algorithm, nothing more and nothing less. SSL attempts to establish that the server you're connecting to is really who it says it is. To do that, it uses a certificate that can be traced back to somebody you (are supposed to be able to) trust.
DH, by itself, only keeps others from reading the transmitted data. SSL is intended to establish considerably more than that (but can use DH to keep others from reading the stream).
Just for an obvious example, using DH (by itself) a Man in the middle attack is fairly simple. If I can get you to connect to my server instead of the one you intended to, I can use DH to establish a "secure" session with you. I then connect to the server you originally intended to. Every packet I get from you, I decrypt, re-encrypt with a key I used to connect to that server, and send on to that server. I do the same with all its response packets. To you, everything looks like it came directly from the original server, and the purchase you made (for example) works just like normal. The only thing that changes is that I also store your credit card number, and when you try to fill your car with fuel the next day, the charge is declined, because in the meantime I've spent all your credit.
The authentication in SSL is at least intended to prevent that from happening. If your browser tried to connect to (for example) www.amazon.com, it should give you a warning if my SSL certificate doesn't specify that it was issued to www.amazon.com -- and a CA shouldn't issue such a certificate to anybody but Amazon.
DH, by itself, doesn't really even guarantee most of what I've said above. By itself, DH is just a way to exchange a key (or, perhaps it could be phrased as "exchange information necessary for both parties to create identical keys, without ever exchanging the key itself in the clear"). After both parties have the key, they can (and presumably will) use it to encrypt/decrypt data -- but that encryption is actually separate from DH itself.
Actually Diffie-Hellman is a part of SSL.
But one part does not replace others.
From here SSL Diffie-Hellman is used for:
This a Diffie-Hellman key exchange in
which the server's certificate
contains the Diffie-Hellman public
parameters signed by the certificate
authority (CA). That is, the
public-key certificate contains the
Diffie-Hellman public-key parameters.
The client provides its Diffie-Hellman
public key parameters either in a
certificate, if client authentication
is required, or in a key exchange
message. This method results in a
fixed secret key between two peers,
based on the Diffie-Hellman
calculation using the fixed public
keys.
You can use anonymous Diffie-Hellman key agreement with SSL. This provides privacy on the channel, but no authentication.
Of course, without authentication, you really can't have privacy, because your private channel could be connected to a "man-in-the-middle". That's why the anonymous DH cipher suites are discouraged.
If the lack of a certificate is stopping you from using SSL where it's really needed, get a free one from startcom.org.
Diffie-Hellman key exchange is only for keyexchange. It does not give you authenticitation (who you're talking to), you need certificates and a PKI for that.
So yes you can do encryption, but you dont know with who you're talking to
The DH key exchange cannot, of itself, do encryption. It is used to establish a session key, but not to do the encryption. So, at this level, the question is mis-stated or reveals either lack of precision or lack of understanding (I suspect precision is the problem this time).
The question is:
Do you want to encrypt data with anybody at all?
Do you want to be sure who you are talking to?
As already pointed out, SSL uses a DH key exchange to establish a session key. However, it also ensures that the program on the other end is someone you trust (directly or indirectly). If you don't need to worry about whether the other person is trustworthy, you could just use a simple DH key exchange and then send encrypted data without needing certificates. But you won't be sure who you are talking to unless you validate that - and the certificates used by SSL etc helps with that validation.

Resources