3

Scenario

We are developing an application that uses a Java frontend and implements more complex mathematical algorithms C++ side. For this purpose there are Java native functions implemented via JNI, to access C++ functionality via Java.

Problem

Historically we had the problem of more and more credentials flying around the relatively large codebase, almost all of it Java side, some configurable credentials in application specific configuration files, the latter can be ignored w.r.t. the scope of this question.

We would like to increase application security. The problem we are facing is that our application must be able to run offline, therefore whatever private key we use to decrypt our data, it will be delivered with the application. We are considering our options, but none of them seem the least bit secure:

  • Keep passwords Java side and use crypto package - still, the encryption algorithm can be identified and the password to encrypt with must still be stored openly somewhere, so this can be decrypted relatively easily. In addition JARs are relatively well accessible.
  • Keep passwords C++ side and use a function decryptKey by passing it a password, decrypting it C++ side with a private key, then returning it plain. In this case JNI becomes the vulnerability, because it is easily conceivable to just build your own JAR, include our DLL and then access the native decryptKey function to retrieve plain-text passwords.
  • Shift all key dependent logic to C++. This makes little sense, because we would have to shift logic where it does not belong. In addition some implementations require 3rd party Java APIs that need to be fed credentials, so this is sadly not an option.

Question

Presumably this is not an uncommon problem in the industry, so what is the most sensible way to handle this? Currently these approaches only introduce security through obscurity, the effectiveness of which is at best debatable and at worst barely above zero. Are there standard procedures how this is handled in the industry?

Community
  • 1
  • 1
Koenigsberg
  • 1,726
  • 1
  • 10
  • 22
  • 1
    A **challenge-response** algorithm (generally used for authentication) is more erratic (better than key rotation). And keys packed in a key store of course. – Joop Eggen Nov 05 '19 at 09:39
  • "*whatever private key we use to decrypt our data, it will be delivered with the application*" ... you are doomed. – rustyx Nov 06 '19 at 13:52

1 Answers1

4

First, your product needs to be able to integrate with products that can keep your private keys safe. These products include TPM, HSM and KMS. This will prove extermely usefult for local and cloud based prduction environments.

Secondly, you should implement an envelope encryption mechanism, where the data encryption key is encrypted with a master key that will be stored in the TPM/HSM/KMS. The encrypted data encryption key can be stored with the data.

Thirdly, you should implement key rotation, where you replace your master/data keys every once in a while.

Fourthly and finally, you should consult Information Security instead of Stackoverflow with future hardening questions.

Shloim
  • 5,281
  • 21
  • 36
  • Thank you for your response. One thing I keep wondering about this is - even if keys are stored securely, as they are retrieved Java side, they can still be read easily. Unless I am missing something, the things proposed do not protect against this, other than possibly introducing key rotation / challenge-response. – Koenigsberg Nov 05 '19 at 15:33
  • 1
    These are different concerns. a TPM/KMS/HSM is used to solve the "encryption at rest" problem, where if someone steals your disk drive with the data on it, it shall be unusable. Other concerns such as "live" hacking attempts are solved by hardening the process, operating system, and using code analysis tools to detect possible security holes such as, SQL injection, cross-site scripting, buffer overflows, etc. – Shloim Nov 06 '19 at 08:39