How Kerberos krb5p does encryption? - encryption

All,
I am trying to mount a NAS drive to a Linux VM.
I have a requirement to encrypt the data in transit, i.e. I want data to be encrypted when
its written from the Linux to the NAS dribe
https://www.dellemc.com/hu-hu/collaterals/unauth/technical-guides-support-information/products/storage/docu88304.pdf
As per the above link krb5p provides encryption of data.
krb5p: Kerberos authentication, data integrity, and data privacy by encrypting the data before sending it over the network. Data encryption requires additional
https://www.varonis.com/blog/kerberos-authentication-explained/
I understand how Kerberos mutual-authentication works but once access is granted to the service (in my case the NAS drive) how does the data transferred to the NAS gets encrypted.
Can someone provide additional details or documentation on how "encryption" works with krb5p?
I am unable to find any additional details.
As per:
https://whyistheinternetbroken.wordpress.com/tag/krb5p/
when using krb5p:
NFS packets will be encrypted with the enctype specified in the Kerberos configuration.
But what are the available enctype that can be specified?
I have attached a diagram that tries to explain the flow of messages b/w Server-KDC-Client

Kerberos allows mutual authentication between a client and a KDC, the KDC and a service, and a client and a service. This happens by way of key agreement between each party.
Client and KDC prove knowledge of a shared key, KDC and service prove knowledge of a different shared key, so client and service can generate yet another random key and agree with one another.
In other words when the client sends the ticket to the service it contains a secret key that both parties can use to encrypt data after authentication has succeeded. In this case that key is what is used to protect NFS traffic.
What enctype is selected is somewhat undefined. It's up to all three parties to agree on one, and each has an opportunity to change it. In practice it's up to the service to make the final decision though. It should be whatever it thinks the strongest algorithm the client can handle. This usually means RC4, AES128, or AES256.

Kerberos just provides the encryption key, but it doesn't magically perform the encryption itself – that has to be done by the NFS client and NFS server themselves. They are aware that krb5p was negotiated, and will call the corresponding encryption/decryption functions when needed. (More specifically, it happens in the SunRPC layer, which NFS is built on.)
When the Kerberos KDC issues you a ticket for "nfs/yourserver.example.com", that ticket includes two copies of a randomly generated session key: one copy decryptable by you, and the other copy decryptable by that server.
The KDC will mark this session key with the best enctype that is common between what was indicated in your ticket request, and what long-term keys are held by the server's principal. Usually this will be AES256-CTS, though it can be RC4 (arcfour) if the service key hasn't been changed in a very long time.
For example,
The "nfs/yourserver.example.com" principal has long-term keys for aes256-cts-sha1-96, aes128-cts-sha1-96, arcfour-hmac, des3-cbc.
Your client making the AS_REQ indicates support for aes256-cts-sha384, aes128-cts-sha256, aes256-cts-sha1-96, aes128-cts-sha1-96.
The KDC chooses aes256-cts-sha1-96 as the best enctype for the session key.
This indication is stored in the ticket itself. If the client is using MIT Krb5 software, you can use kvno to manually request a service ticket (if you don't have one yet) and then klist -e to see the enctypes set for that ticket – "skey" indicates the enctype that the session key is meant to be used with.
So after receiving the ticket from the KDC, you send it to the NFS server as part of the RPCSEC_GSS authentication process, and now both you and the server have copies of the session key. (The same session key remains in use for as long as the service ticket is valid – usually 10 hours.)
The set of possible enctypes is:
aes256-cts-hmac-sha384-192, aes128-cts-hmac-sha256-128: New, not supported by most implementations yet (and most services won't have keys of that type yet, either).
aes256-cts-hmac-sha1-96, aes128-cts-hmac-sha1-96: Widely supported by all Kerberos implementations.
camellia256-cts-cmac, camellia128-cts-cmac: Decent alternatives to AES, but rarely used in practice.
arcfour-hmac (RC4): Deprecated, but still occassionally used. Gone from Linux 5.10.
des3-cbc-sha1: Deprecated, but still implemented.
des-cbc-md5, des-cbc-crc: Completely obsolete. Hope you'll never see those.
(Don't believe webpages saying that Linux NFS client only supports DES – that was fixed in 2010 for v2.6.35, and AES is fully supported now.)

Related

Libsodium and Perfect Forward Secrecy

I'm thinking of creating a mobile app that uses Libsodium's crypto_box_easyfor encrypting and decrypting chat messages.
However, after reading a lot on the net, I found that one of the major flaws of public-private-key algorithms is that recorded data can be decrypted as soon as the recipients private key is leaked.
To avoid that, the use of Perfect Forward Secrecy (PFS) is suggested and I'm wondering, if Libsodium is already supporting PFS in the former mentioned function as individual nonces are used for each encryption.
Maybe someone can guide me on the difference between PFS and Libsodiums functions (if there are some) or help me by clarifying the relationship of nonces and PFS.
There is no forward secrecy.
crypto_box_seal() is slightly better, as the sender uses ephemeral keys. These messages can be signed using a long-term secret key in order to check that they come from the expected party, but that key being compromised will not allow decryption of previous messages.
However, if the recipient's secret key get compromised, recorded messages can still be decrypted.
For these reasons, the box construction doesn't exist in libhydrogen. Instead, there are Noise-based protocol implementations for secure key exchange, all with forward secrecy. These APIs will be backported to libsodium at some point.
But secure chat applications are far from trivial to build. The signal library is a much better starting point, even though the license may not be compatible with your expectations.

RADIUS with MS-CHAPv2 Explanation

Can't find any flowcharts on how communication works between peers. I know how it works in Radius with PAP enabled, but it appears that with MS-Chapv2 there's a whole lot of work to be developed.
I'm trying to develop a RADIUS server to receive and authenticate user requests. Please help me in the form of Information not code.
MSCHAPv2 is pretty complicated and is typically performed within another EAP method such as EAP-TLS, EAP-TTLS or PEAP. These outer methods encrypt the MSCHAPv2 exchange using TLS. The figure below for example, shows a PEAP flowchart where a client or supplicant establishes a TLS tunnel with the RADIUS server (the Authentication Server) and performs the MSCHAPv2 exchange.
The MSCHAPv2 exchange itself can be summarized as follows:
The AS starts by generating a 16-byte random server challenge and sends it to the Supplicant.
The Supplicant also generates a random 16-byte peer challenge. Then the challenge response is calculated based on the user's password. This challenge response is transmitted back to the AS, along with the peer challenge.
The AS checks the challenge response.
The AS calculates a peer challenge response based on the password and peer challenge.
The Supplicant checks the peer challenge response, completing the MSCHAPv2 authentication.
If you'd like to learn about the details and precise calculations involved, feel free to check out my thesis here. Sections 4.5.4 and 4.5.3 should contain all information you need in order to implement a RADIUS server capable of performing an MSCHAP exchange.
As you can see in the figure, many different keys are derived and used. This document provides a very untuitive insight into their functionality. However, the CSK is not explained in this document. This key is optionally used for "cryptobinding", i.e. in order to prove to the AS that both the TLS tunnel and MSCHAPv2 exchange were performed by the same peer. It is possible to derive the MSK from only the TLS master secret, but then you will be vulnerable to a relay attack (the thesis also contains a research paper which gives an example of such an attack).
Finally, the asleap readme gives another good and general step by step description of the MSCHAPv2 protocol, which might help you further.
Unfortunately i can't add anymore comments, the demand is for me to have 50 reputation.
To your request:
My lab enviorment is of SSL-VPN used with AS of RADIUS.
Constructed with the following 3 items:
End-User -> there's no 'client' installed, the connection starts through a web portal. client = web browser
NAS -> This is the machine that provides the web-portal(the place the End-User enters the Username & Password) AND acts as a RADIUS CLient, transfering requests to the AS.
AS(RADIUS) -> This is me. I receive the access-requests and validate the username & password.
So in accordance with that, what i receive in the Access-Request is:
MS-CHAP2-Response:
7d00995134e04768014856243ebad1136e3f00000000000000005a7d2e6888dd31963e220fa0b700b71e07644437bd9c9e09
MS-CHAP-Challenge: 838577fcbd20e293d7b06029f8b1cd0b
According to RFC2548:
MS-CHAP-Challenge This Attribute contains the challenge sent by a NAS to a Microsoft Challenge-Handshake Authentication Protocol (MS-CHAP) user. It MAY be used in both Access-Request and Access-Challenge packets.
MS-CHAP2-Response This Attribute contains the response value provided by an MS-
CHAP-V2 peer in response to the challenge. It is only used in
Access-Request packets.
If i understand correctly, and please be calm this is all very new to me, based on your flowchart the AS is also the Authenticator who inits the LCP.
And in my case, the LCP is initiated by the NAS, So my life made simple and i only get the Access-Request without needing to create the tunnel.
My question now is, how do i decrypt the password? I understood there's a random challenge 16-byte key but that is held by the NAS.
From my recollection, i only need to know the shared secret and decrypt the whole thing using the algorithem described in your thesis.
But the algorithem is huge, i've tried different sites to see which part of it the AS supposed to use and failed in each attempt to decrypt.
Since i can't ask for help anymore in this thread, i can only say this little textbox cannot fill the amount of gratitude i have for your help, truely lucky to have you see my thread.
Do email me, my contact info are in my profile.
Also, for some reason i can't mark your answer as a solution.
"is typically performed within another EAP method such as EAP-TLS, EAP-TTLS or PEAP."
Well...
RADIUS win2008 server here, configured to NO EAP, only MS-CHAPv2 encryption, to replace the PAP.
This is why alot of what you said and what i said wasn't adding up...
I'm not MITM, i'm the AS, and my NAS(the one who knocks) is the RADIUS_Client/Authenticator.
When the user enters UN&PW a random encryption, which i'm now on the look for, is created with MS-CHAPv2 and all of the above is irrelevant.
With the items received from the Authenticator which again are:
- Username, MS-CHAP-Challenge, MS-CHAP2-Response
The AS performs a magical ceremony to come up with the following:
-Access-Accept
-MPPE-Send-Key
-MPPE-Recv-Key
-MS-CHAP2-Sucess
-MS-CHAP-DOMAIN
This is from a working scenario, where i have a RADIUS server, a radius client and a user.
A NOT working scenario, is the one where i am the RADIUS Server(AS), cause that's my goal, building a RADIUS server, not MITM.
So all i got left is finding out what decryption algorithem needed for those and how.

Authentication keys in smart cards

I use JCManager tool load applets on my java-cards. This software has three fields for authentication keys in the top named S_ENC, S_MAC and DEK.
As I know, ENC stands for Encryption, MAC stands for Message Authentication Code and DEK stands for Data Encryption Key.
I want to know when they used (which step in communication? INITIAL UPDATE , EXTERNAL AUTHENTICATION? ... )?
Does all of these three keys, used in every communications or some of them are optional to use?
and where? (Card or Terminal or both?)
And also, I want to know what is KEK? Is there any KEK in smart cards?
Read the Global Platform Card specifications (registration required) on how the keys are used. The way they are used during authentication differs in the Global Platform specification, so it's better to go straight to the source. For instance E.4.2. of GPC 2.2 specifies:
Generating or verifying an
authentication cryptogram uses the S-ENC session key and the signing method described in appendix
B.1.2.1 - Full Triple DES.
The DEK - or a key derived from the given DEK - is uses for additional encryption of confidential data, such as keys. It would for instance allow for wrapping of keys within a Hardware Security Module, before sending it over the secure message channel (which may not encrypt at all, mind you). For older schemes it was required to also derive a DEK session key, which - paired with the awkward proprietary key derivation - made it near impossible to do so without programming the HSM specifically for Global Platform.
DEK is a more generic term than KEK (Key Encryption Key). I can be used for any data that needs to be kept confidential separate from the transport channel.

Is it insecure to pass initialization vector and salt along with ciphertext?

I'm new to implementing encryption and am still learning basics, it seems.
I have need for symmetric encryption capabilities in my open source codebase. There are three components to this system:
A server that stores some user data, and information about whether or not it is encrypted, and how
A C# client that lets a user encrypt their data with a simple password when sending to the server, and decrypt with the same password when receiving
A JavaScript client that does the same and therefore must be compatible with the C# client's encryption method
Looking at various JavaScript libraries, I came across SJCL, which has a lovely demo page here: http://bitwiseshiftleft.github.com/sjcl/demo/
From this, it seems that what a client needs to know (besides the password used) in order to decrypt the ciphertext is:
The initialization vector
Any salt used on the password
The key size
Authentication strength (I'm not totally sure what this is)
Is it relatively safe to keep all of this data with the ciphertext? Keep in mind that this is an open source codebase, and there is no way I can reasonably hide these variables unless I ask the user to remember them (yeah, right).
Any advice appreciated.
Initialization vectors and salts are called such, and not keys, precisely because they need not be kept secret. It is safe, and customary, to encode such data along with the encrypted/hashed element.
What an IV or salt needs is to be used only once with a given key or password. For some algorithms (e.g. CBC encryption) there may be some additional requirements, fulfilled by chosing the IV randomly, with uniform probability and a cryptographically strong random number generator. However, confidentiality is not a needed property for an IV or salt.
Symmetric encryption is rarely enough to provide security; by itself, encryption protects against passive attacks, where the attacker observes but does not interfere. To protect against active attacks, you also need some kind of authentication. SJCL uses CCM or OCB2 encryption modes which combine encryption and authentication, so that's fine. The "authentication strength" is the length (in bits) of a field dedicated to authentication within the encrypted text; a strength of "64 bits" means that an attacker trying to alter a message has a maximum probability of 2-64 to succeed in doing so without being detected by the authentication mechanism (and he cannot know whether he has succeeded without trying, i.e. having the altered message sent to someone who knows the key/password). That's enough for most purposes. A larger authentication strength implies a larger ciphertext, by (roughly) the same amount.
I have not looked at the implementation, but from the documentation it seems that the SJCL authors know their trade, and did things properly. I recommend using it.
Remember the usual caveats of passwords and Javascript:
Javascript is code which runs on the client side but is downloaded from the server. This requires that the download be integrity-protected in some way; otherwise, an attacker could inject some of his own code, for instance a simple patch which also logs a copy of the password entered by the user somewhere. In practice, this means that the SJCL code should be served across a SSL/TLS session (i.e. HTTPS).
Users are human beings and human beings are bad at choosing passwords. It is a limitation of the human brain. Moreover, computers keep getting more and more powerful while human brains keep getting more or less unchanged. This makes passwords increasingly weak towards dictionary attacks, i.e. exhaustive searches on passwords (the attacker tries to guess the user's password by trying "probable" passwords). A ciphertext produced by SJCL can be used in an offline dictionary attack: the attacker can "try" passwords on his own computers, without having to check them against your server, and he is limited only by his own computing abilities. SJCL includes some features to make offline dictionary attacks more difficult:
SJCL uses a salt, which prevents cost sharing (usually known as "precomputed tables", in particular "rainbow tables" which are a special kind of precomputed tables). At least the attacker will have to pay the full price of dictionary search for each attacked password.
SJCL uses the salt repeatedly, by hashing it with the password over and over in order to produce the key. This is what SJCL calls the "password strengthening factor". This makes the password-to-key transformation more expensive for the client, but also for the attacker, which is the point. Making the key transformation 1000 times longer means that the user will have to wait, maybe, half a second; but it also multiplies by 1000 the cost for the attacker.

Which of the encryption approaches should I use?

I need a system to exchange very secret data (source code that is a trade secret). I will use Crypto++ so practically I can use all encryption algorithms, although I really prefer to use an industry standard.
Currently I'm thinking on these methods:
Have the server generate 2048/4096-bit RSA keys, send the public key over to the client, have the client encrypt the data then send it over to the server.
Use a key exchange method like Diffie-Hellman (Diffie-Hellman-Merkle to be correct) to exchange an AES-256 key.
Initiate a TLS connection and tell the server the AES key directly.
Which approach do you believe I should use? I'm not concerned about performance as long as it's reasonable; security is what matters. If none of them, please suggest another method.
P.S.: I might use chaining on the symmetric algorithm, like AES-Twofish-Serpent.
EDIT: Any recommended software must be in a license that won't restrict proprietary usage. LGPL is as restrictive as it must get. That rules out GPL.
Don't develop your own key exchange and/or key provisioning protocol(s). This is what historically breaks most products and, unless you are a cryoptographer (not a programmer with crypto experience), you'll likely get it wrong.
Use off-the-shelf protocols like SSL/TLS. Eg. TLS initialized with RSA keypairs for mutual authentication and AES session keys sounds appropiate for what you describe
Updated
Bruce Schneier:
"A colleague once told me that the world was full of bad security
systems designed by people who read
Applied Cryptography"
erickson in his post has already give you plenty of evidence why designing your own key provisioning and management protocol is flawed. I just want to drive the point home why Mallory is alive and doing quite well, thanks to overconfident developers:
You design the scheme you propose where the client encrypts with a public key and sends the document back to you. Things work great, but 1 year down the road the certificate is approaching expiration. You send an email out to your clients with the new certificate containing the public key you want your users to sign encrypts the documents with for you. Unknown to you is that over the past 4 months your ISP admin has received a bribe to route all your IP traffic through a remote machine. Your email is intercepted before distribution and your attached certificate is replaced with another one. All your clients are now sending their ultra secret documents encryted for someone else's private key. An application decrypts each one, stores it, then encrypts it with your public key and forwards the traffic to you. You won't even know is happening, untill by accident during a visit to a client's site you notice that the certificate he uses is not the one you distributed.
You mention in your post as an option to chain algorithms. Nobody is going to brute force you. Your weakness will be key management, and the attack will take some form of social engineering to fool someone is using the wrong key, or reveling the private key (again, bribes go a long way). Industry agreed protocols have steps to prevent man-in-the-middle attacks, they may rely on PKI infrastructure that recognizes designated key use and trusted authorities, they add certificate revocation list check steps to the validation etc etc. Just 'I encrypt with public key, you decrypt with private' does not make a secret safe.
I'd recommend using an existing S/MIME (or CMS) implementation with a solid cryptographic module to encrypt your content.
S/MIME enveloped data makes a nice format for storage of encrypted data "at rest": the envelope records information about the algorithms and keys used so that the information will be available to authorized recipients later, when it is needed.
Also, even if it doesn't support the "best" algorithms (like ECDH key agreement), a good library is much less likely to have vulnerabilities than something written by a general programmer. Since it is far, far more likely that security will be breached by an implementation error than cryptanalysis, it makes sense to minimize those errors.
In legitimate protocols, public keys are signed by one of a small number of trusted issuers, whose public keys are distributed by some secure means "out-of-band". If you already have a secure means to get a public key to the message sender, why bother sending another? And if you don't, you're screwed.
TLS and S/MIME depend on having a set of well known CA certificates at every client. These are used to sign the server's public key so that a client can detect attempts to substitute keys. The protocol can't bootstrap itself; there must be a secure way to distribute "trust anchors" out-of-band.
Also note that RSA is incredibly slow compared to symmetric ciphers. Real protocols generate a "content encryption key" for a symmetric algorithm like AES, then use an RSA public key as a "key encryption key" to encrypt the content encryption key for the message recipient(s).
So, the main problem is getting your public key to the client securely. If you can do that, either option #1 or #2 is good—assuming that you just use that public key, rather than trying to send another one "in-band". In fact, in CMS, Option #1 is called "key transport", and Option #2 is called "key agreement".
In practice, the "server" could use a certificate issued by a CA that is already well known, or the client can compare a hash of the certificate with one that you tell him over the phone, or carve into the face of a cliff, or whatever. The critical thing is, all of your security depends on the integrity of the certificate. You have to protect it from tampering.
While Crypto++ is an "industry standard", its security depends on how you use it. Just like Jerry told Kramer, "the door must be… closed!" Using the cryptographic primitives in Crypto++ with in a poorly designed protocol will get you nowhere. That's why I'm stressing the use of CMS (a higher-level protocol) together with a good cryptographic module (cryptographic primitives).
What about ssh ? (rsync on ssh for example) ?

Resources