Don't try to erase secrets from memory.

1. The things we're really trying to protect - contact identities,
message contents, etc - can't be erased from memory because they're
encapsulated inside objects we don't control.

2. Long-term secrets can't be protected by erasing them from memory
because they're stored in the database and the database key has to be
held in memory whenever the app's running.

3. If the runtime uses a compacting garbage collector then we have no
way to ensure an object is erased from memory.

4. Trying to erase secrets from memory makes the code more complex.

Conclusion: Let's not try to protect secrets from an attacker who can
read arbitrary memory locations.
This commit is contained in:
akwizgran
2014-12-29 21:08:27 +00:00
parent f316d64afa
commit 358166bc12
28 changed files with 211 additions and 557 deletions

View File

@@ -89,7 +89,7 @@ public interface CryptoComponent {
* given password. The ciphertext will be decryptable using the same
* password after the app restarts.
*/
byte[] encryptWithPassword(byte[] plaintext, char[] password);
byte[] encryptWithPassword(byte[] plaintext, String password);
/**
* Decrypts and authenticates the given ciphertext that has been read from
@@ -97,5 +97,5 @@ public interface CryptoComponent {
* given password. Returns null if the ciphertext cannot be decrypted and
* authenticated (for example, if the password is wrong).
*/
byte[] decryptWithPassword(byte[] ciphertext, char[] password);
byte[] decryptWithPassword(byte[] ciphertext, String password);
}

View File

@@ -16,9 +16,6 @@ public interface KeyManager extends Service {
*/
StreamContext getStreamContext(ContactId c, TransportId t);
/**
* Called whenever an endpoint has been added. The initial secret is erased
* before returning.
*/
/** Called whenever an endpoint has been added. */
void endpointAdded(Endpoint ep, int maxLatency, byte[] initialSecret);
}

View File

@@ -12,5 +12,5 @@ public interface PasswordStrengthEstimator {
* Returns an estimate between 0 (weakest) and 1 (strongest), inclusive,
* of the strength of the given password.
*/
float estimateStrength(char[] password);
float estimateStrength(String password);
}

View File

@@ -1,21 +1,15 @@
package org.briarproject.api.crypto;
/** A secret key used for encryption and/or authentication. */
public interface SecretKey {
public class SecretKey {
/** Returns the encoded representation of this key. */
byte[] getEncoded();
private final byte[] key;
/**
* Returns a copy of this key - erasing this key will erase the copy and
* vice versa.
*/
SecretKey copy();
public SecretKey(byte[] key) {
this.key = key;
}
/**
* Erases this key from memory. Any copies derived from this key via the
* {@link #copy()} method, and any keys from which this key was derived via
* the {@link #copy()} method, are also erased.
*/
void erase();
public byte[] getBytes() {
return key;
}
}