is KDC better than using symmetric keys and digitally signing for messages?

Lets say some bank sends messages between its own branch related to deposits and withdrawals. Messages are encrypted with symmetric keys and digitally signed in order to insure that messages cannot be read or altered.

Is this still vulnerable to any specific kind of attack? How could it be made as secure as possible? Is KDC a solution?

Is AES the recommended symmetric cipher for production level software?

I was considering developing an application level software for file encryption after stress testing many of my implementations of popular symmetric ciphers. I would love to support multiple algorithms like AES (GCM / CBC/ CTR) , XChaCha20-Poly1305 etc. But I’m on crossroads when choosing a very recommended symmetric cipher for my application, when it comes to performance as well as secure implementation. AES has been tried and tested for years and is still the most popular symmetric cipher in the world. It’s well documented and also standardized by various Governments (FIPS standard for example) , but very difficult to implement securely unless hardware acceleration is available. Pure software version of AES is slow and my application should be able to achieve the same performance on many devices. Also, AES GCM has a maximum size limit for messages ~ 64 GB, and I really wanted authentication with encryption!

  • Should I stick with AES and its various modes (ex. CTR HMAC SHA256) or is it time to adopt a new symmetric cipher like XChaCha20 or XSalsa20 with Poly1305, which is easy and secure to implement in software, but unfortunately not standardized yet ?

  • Also, why using a standardized cipher is recommended in production quality software?

Symmetric versus asymmetric self encryption

I can encrypt my files with a symmetric encryption algorithm like AES, or with an asymmetric encryption algorithm like RSA or ECC (I encrypt my files with my own public key). No communication is involved in this scenario. The latter, called asymmetric self encryption, might seem an unusual choice in situations where key exchange is not required. However, it still does have some advantages: you don’t need to type your passphrase for encryption (you need your public key); it works well with keys stored in a hardware token; also an attacker apparently needs both to have the public key and brute-force the passphrase to decrypt the data. In GnuPG, these two encryptions are achieved via options gpg -c and gpg -e -r USERNAME.

  1. Considering attacks on the asymmetric encryption, does hiding the public key increase the entropy required for a brute force attack? What information the public key provide to the attacker?
  2. In practice, how do you compare AES 256, RSA 4098, ECC Curve25519, Brainpool p-12 and seckp256k1, in terms of security, speed and utility (compatibility, implementation, etc)?

Are there any reasons for Kerberos being based on symmetric cryptography?

Kerberos is an authentication protocol that is famously built using only symmetric ciphers.

As a direct result of this, there are several attacks possible, such as

  • AS-REP Roasting
  • AS-REQ Roasting
  • Kerberoasting
  • Silver Tickets
  • Golden Tickets

While some attacks require specific conditions (e.g. AS-REP Roasting requires disabling pre-authentication), other attacks like AS-REQ Roasting cannot be prevented at all.

It seems odd to me to use symmetric cryptography for a task that just screams “Please use asymmetric cryptography for this!”. Is there something I am missing? What are the reasons for choosing symmetric ciphers?

Algorithm to implement symmetric encryption in VB.Net for Windows and in Swift for iOS

I need to implement symmetric encryption to enable secure communication between one program running on a Windows machine (to be written in VB.Net) and an app running on an iOS device (to be written in Swift). I’d like to use a reasonably modern algorithm which is supported in both programming languages “out of the box” without having to import more code than necessary.

The use case is, information (mostly, text files) will be encrypted by one program (say, running on Windows) and uploaded to a server, where it will be stored, then later downloaded and then decrypted by the other program (running on iOS). The server doesn’t need access to the content of the file, and having the information “encrypted at rest” on the server is the main goal, although having it encrypted during transit to/from the server is also beneficial. The Windows and the iOS devices themselves aren’t considered to be targeted in this case.

What algorithm(s) are good choices as being modern, secure, and available in both Swift and Dot Net so that what’s encrypted by one can be decrypted by the other?

Establish a symmetric key: KDF based on shared secret and random salt or key wrapping?

I am designing a basic KMS based on a simple HSM, I only have access to: AES256, SHA256, PBKDF2, HMAC (and combinations like AES256-HMAC-SHA256). The admin and the users of the system have a personal HSM where the keys are stored and it works like this:

  1. The administrator generates a key inside his HSM with PBKDF2 (random salt and random seed)
  2. The HSM of the administrator encrypts the new key using AES-256 with a different symmetric key for each user (the key used for key wrapping was established during the physical initialization of the HSM of the user) and sends it to every user that needs it along with key’s metadata. The whole payload (encrypted key value + key’s metadata) is encrypted another time with AES256 with another unique key for each user.
  3. The payload reaches the user that, thanks to the two symmetric keys previously shared with the admin (during the HSM physical initialization), is able to retrieve the requested key and metadata.

I was thinking about another possible approach that could be better but I am not really sure about it:

  1. The administrator establishes a shared secret common to every user of the system. This secret is stored in every HSM belonging to the users or to the administrator.
  2. When a key must be generated, the administrator computes it with PBKDF2 using the common secret and a random salt.
  3. When a key must be sent to any user, only the salt that was used by the administrator is actually sent to the user. The salt may be encrypted with a pre-shared symmetric key (like the example above) and it is used by every user along with the shared secret to generate again the key.

The first approach has the following problems: I need to send the actual key value, I have to perform two encryptions, the HSM must offer an API to retrieve from its internal flash memory the actual value of a key (as cleartext or ciphertext depending on the choice of the caller, the API can be called only if the administrator is logged in the HSM and it can’t be called if the user is logged).

The second approach has the following problems: the secret is common to all users so if an attacker finds the secret of a single user, he founds the secret of everyone. The HSM must offer an API to retrieve the secret as cleartext from its internal flash memory because the secret must be the same for every user, even for users that are added to the system weeks/months later (again this API is callable only if the administrator is logged in the HSM).

I suppose that the second approach, in principle, could be better because the keys are not actually sent from the administrator to the users. But the secret common to everybody is a problem, moreover I imagine that if an attacker finds out the value of a random salt, he may simply try to compute all possible keys given that salt using PBKDF2 and all possible seeds (because the implementation is open source so he knows that the secret is 32 bytes long and he also has access to the PBKDF2 code).

In conclusion I think that in the real world the first approach is more secure, provided that the login as administrator to the HSM is protected by a very complex PIN and possibly by a second factor (i.e. fingerprint). Do you agree? Any thoughts about other vulnerabilities in my approach?

Is this symmetric key system secure?

I am creating a secure network data transfer system, and would like to know if there are any obvious flaws in this scheme.

Secrets

The secret is a password that is known to both clients. This password is never transferred plaintext, nor is the PBKDF2 password hash.

Server side

The server never stores the password permanently. The password is salted using a random 16-byte salt and hashed using PBKDF2-SHA256 with at least 30000 iterations (the number of rounds is configurable).

Client side

The client has the password in plaintext.

Notification

The server notifies the client via a UDP packet that has a sensitive information field, "source". The packet looks similar to the following:

{     "proto": <protocol version as integer, starting at 1 for the first version>,     "host": <address of sender to communicate privately with, as string>     "port": <port of sender to communicate privately with, as string>     "source": <source of data. Note that this field is encrypted using                PKCS#7/AES-256-CBC with "iv" as the initialization vector                and the 32-byte password hash as the key>     "iv": <16-byte IV for encrypting "source">     "salt": <password salt that password hash was derived with>     "rounds": <number of PBKDF2 rounds that password hash was derived with>     "hmac": <HMAC-SHA256 of {iv || source}, using the password hash as key>     "time": <time ping was sent, as string>,     "manual" <boolean whether ping was a manual send (true) or automatic change notice (false)>     "ping": true } 

where || is concatenation. The 32-byte PBKDF2-SHA256 result, with provided salt and rounds, makes up the encryption key for “source”.

The IV obviously prevents identical messages from having the same encryption signature, and the HMAC should provide the message authentication.

Client <-> Server

When the client receives the server broadcast, it then initiates a TCP connection to the server to obtain the data. The server then sends this response to set up the connection:

{     "proto": <protocol version as integer, starting at 1 for the first version>,     "iv": <16-byte IV to use for encrypting information>,     "salt": <password salt that password hash was derived with>,     "rounds": <number of PBKDF2 rounds that password hash was derived with> } 

The reason for the server providing the IV is to prevent replay attacks with a known client IV, and the salt and rounds show what the server expects the encryption key to be (again the 32-byte result of the PBKDF2-SHA256 of the password).

The client then sends a request that looks like the following:

{     "proto": <protocol version as integer, starting at 1 for the first version>,     "hmac": <HMAC-SHA256 of {iv || req}, using the password hash as key>,     "req": <binary string containing encrypted packed representation of the following:         {             "source": <source of desired information requested>,             "dest": <destination of desired information requested>,             "user": <Username, as string (empty string if no username)>,         }> } 

The HMAC once again allowing no man-in-the-middle tampering, unless the key is leaked. “req” is encrypted with PKCS#7/AES-256-CBC with the previously sent “iv” as the initialization vector and the 32-byte PBKDF2 hash as the key.

The server responds with a final data packet:

{     "proto": <protocol version as integer, starting at 1 for the first version>,     "hmac": <HMAC-SHA256 of {iv || req}, using the password hash as key>,     "resp": <binary string containing encrypted packed representation of the following:         {             "iv": <16-byte IV to use with the next request on this connection>             .             .             .         }> } 

“resp” is encrypted just the same as “req” in the client request.

Question

Are there any major flaws in this scheme? If so, what are they? I’ve tried to prevent replay attacks by rotating IVs often and ensuring the server generates them, and the encryption key is never sent in plaintext.

Assignment problem with symmetric matrix

I came across a problem which I think can be reduced to the assignment problem/Hungarian algorithm.

We have matrix $ A$ and matrix $ B$ which are both $ n\times n$ symmetric matrices. We can rearrange $ B$ in the following manner: column $ i$ can be swapped with column $ j$ provided that next, row $ i$ is swapped with row $ j$ . This preserves the symmetry of $ B$ .

The problem statement is to find a rearrange of $ B$ in this manner which minimizes the Frobenius norm of $ A-B$ .

Any guidance on an approach would be greatly appreciated. Thank you very much in advance.

Is “represents” a symmetric relation in the provided answer to TAOCP exercise 1.1.9?

In exercise 1.1.9 of volume 1 of The Art of Computer Programming, the reader is asked to

formulate a set-theoretic definition for the concept “$ C_2$ is a representation of $ C_1$

where $ C_1$ and $ C_2$ are computational methods described in the previous few pages (reproduced here so the question can be answered without needing the book).

Let us formally define a computational method to be a quadruple $ (Q,I,\Omega,f)$ , in which $ Q$ is a set containing subsets $ I$ and $ Ω$ , and $ f$ is a function from $ Q$ into itself. […] The four quantities $ Q$ , $ I$ , $ \Omega$ , $ f$ are intended to represent repectively the state of the computation, the input, the output, and the computational rule.

When I looked at the answer in the back, this definition was proposed:

For example we can say $ C_2$ represents $ C_1$ if there is a function $ g$ from $ I_1$ into $ I_2$ , a function $ h$ from $ Q_2$ into $ Q_1$ , and a function $ j$ from $ Q_2$ into the positive integers, satisfying the following conditions:

  • a) If $ x$ is in $ I_1$ then $ h(g(x)) = x$
  • b) If $ q$ is in $ Q_2$ then $ f_1(h(q)) = h(f_2^{[j(q)]}(q))$ , where $ f_2^{[j(q)]}$ means that the function $ f_2$ is to be iterated $ j(q)$ times.
  • c) If $ q$ is in $ Q_2$ then $ h(q)$ is in $ \Omega_1$ if and only if $ q$ is in $ \Omega_2$

Later on, discussing this definition, Knuth writes (emphasis mine):

The relation “$ C_2$ represents $ C_1$ ” generates an equivalence relation in which two computational methods apparently are equivalent if and only if they compute isomorphic functions of their inputs …

To be an equivalence relation, a relation must be symmetric. That is, for a relation $ R$ , $ (a, b) \in R$ implies $ (b, a) \in R$ . I don’t believe this is true of the given definition.

Consider the computational methods $ C_1$ and $ C_2$ , where

\begin{align*} C_2 &= \{Q_2, I_2, \Omega_2, f_2\}\ C_1 &= \{Q_1, I_1, \Omega_1, f_1\}\\ I_2 &= \{a_1, a_2\}\ \Omega_2 &= \{b_1, b_2\}\ Q_2 &= I_2 \cup \Omega_2\ f_2 &= \{(a_1, b_1), (a_2, b_2), (b_1, b_1), (b_2, b_2)\}\\ I_1 &= \{c\}\ \Omega_1 &= \{d\}\ Q_1 &= I_1 \cup \Omega_1\ f_1 &= \{(c, d), (d, d)\} \end{align*}

It can be shown that $ C_2$ represents $ C_1$ by $ g(q) = a_1$ , $ h = \{(a_1, c), (a_2, c), (b_1, d), (b_2, d)\}$ , and $ j(q) = 1$ .

However, $ C_1$ cannot represent $ C_2$ , because for any proposed $ g: I_2 \rightarrow I_1$ it must be the case that $ g(a_1) = g(a_2) = c$ . But $ h(c)$ can only be either $ a_1$ or $ a_2$ . If $ h(c) = a_1$ , then $ h(g(a_2)) = a_1 \neq a_2$ , but if $ h(c) = a_2$ , then $ h(g(a_1)) = a_2 \neq a_1$ . So in either case, the first requirement cannot be satisfied.

Has this been discussed elsewhere? So far my online searches haven’t revealed any answers on the subject. To the best of my knowledge, this hasn’t been errata’d (checked here).

Am I understanding the definition properly?

I’m uncertain about my result because of the specific wording “from $ Q_2$ into $ Q_1$ “, which seems to have varying meanings depending on where you ask (if it means “injection”, it adds different inconsistencies). It also seems strange to me that this property would be overlooked, since Knuth also specifically mentions that “represents” is transitive, and a counterexample like this is quite easily constructed.

In summary: is it not symmetric? Has this been addressed somewhere? Am I owed 0x$ 1.00?