1

The encrypted text is public, embedded in the binary of my software which is published on the internets. I know the open text but there’s large circle of third parties who might know it too, despite it’s a secret (that’s an access key to a cloud provider).

Am I correct that even if the cloud provider leaks the secret text, an attacker then knows both open text and encrypted text, attacker might be able to use these 2 pieces to reconstruct the symmetric AES key, but even then they can’t reconstruct the private EC key I used as a source of that, because Rfc2898DeriveBytes is a one way thing?

Here's C# code which decrypts:

byte[] privateKeyBytes = // private key bytes, decoded Base64 from PEM file in NAND flash
byte[] deriveSalt = new bytes[ 8 ] {…} // data from random.org
var k = new Rfc2898DeriveBytes( privateKeyBytes, deriveSalt, 77 );
byte[] aesKey = k.GetBytes( 16 );
Aes aes = Aes.Create();
aes.Key = aesKey;
aes.IV = new byte[ 16 ] {…} // data from random.org
// Use Aes to decrypt
  • It's very bad practice to grab random data from an external party who you have no idea whether or not the data they give you is actually random. You should use the secure random number generator (System.Security.Cryptography.SecureRandomNumberGenerator or something) to fill your buffers with random data. – user Nov 14 '19 at 20:57
  • @user Thanks, changed IV and the salt. – Soonts Nov 14 '19 at 21:14
2

Yes, it's bad practice to use a key for two different purposes. This can have obvious or subtle problems.

In this specific case, I don't see an obvious security problem. Rfc2898DeriveBytes implements PBKDF2, which is a key derivation function. Given the output, it's impossible to reconstruct the input except by guessing. Since a private key has enough entropy to be unguessable, it's impossible to find privateKeyBytes from k and deriveSalt.

Nonetheless there are several problems in your mechanism.

  • Don't use the EC private key as input. If you need to derive everything from a single key due to extremely limited storage, have a single root secret key and derive everything from that, including your EC private key(s). Derive each key with a different salt.
  • Rfc2898DeriveBytes is not the right kind of function to use here. It's a password-based key derivation function, but you don't have a low-entropy secret such as a password, you have a high-entropy secret. Use an “ordinary” key derivation function such as HKDF or a function from SP 800-108.
  • The salt for derivation does not need to be random. Use a constant salt, with a different value for each key that you derive from the same root. Since you can use the same salt value for a given key on every device running the same code, you can hard-code the salt values in your code.
  • Don't make up randomness by downloading it or other unholy made-up methods. Use your operating system's randomness source, via your cryptography library's random generation API.
  • Thanks for elaborate comments. I have gigabytes of flash storage there, but I can no longer pre-share secrets. The software updates are delivered over the air, their integrity is verified with signatures (hardware has the pre-shared public key), but their content is not secret. That EC private key appears to be the only piece of secret data pre-shared in a secure way. A few people are already testing beta of the device and I don’t have access to these devices anymore. – Soonts Nov 14 '19 at 22:45
  • Salt and AES IV are hardcoded. Initially I got the values from that web service, but after the comment above I’ve replaced with bytes generated on my desktop PC. – Soonts Nov 14 '19 at 22:45
  • @Soonts If you can store secrets, generate keys independently. If you need to share those keys, do it over a TLS session authenticated by the initially-provisioned EC key. – Gilles 'SO- stop being evil' Nov 14 '19 at 23:17
  • I can store secrets but I’m not sure how to add more of them after the devices are shipped. I don’t have a web server on the internet which I trust. Devices trust my updates because the devices have a pre-shared public key to verify the authenticity of updates. Devices don’t have public IP addresses so I can’t connect to them to deploy new secrets. – Soonts Nov 14 '19 at 23:27
  • 1
    @Soonts Please don't take it badly, but as a professional of secure device deployment, I will say that given your level of understanding of the cryptography involved, I find it very unlikely that you will manage to build something that's secure. You can ask more questions here, but you'd need to explain your system in a lot more detail (including business details you may not want to reveal), and it's hard to even guide you into asking the right questions. I recommend that you hire someone with the right security competence. Now, rather than after your device is hacked. – Gilles 'SO- stop being evil' Nov 15 '19 at 7:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.