Sorry dummy question but at application creation time (and when resetting the secret), in the response of the POST , the master secret should be returned to the user, right ? Otherwise he will never get it.

And second question, I know Security is not often a good mate with UX but , the console will never show the master/variant secret anymore ?  


On Wed, Apr 16, 2014 at 6:57 PM, Bruno Oliveira <bruno@abstractj.org> wrote:
Hi Karel, this not bullet proof but let me try to explain. Currently you
can only send push messages if you have the master secret, currently I
can see two points of vulnerability: 1) client side in possession of
master secret, 2) database storing master secret. We can't do so much
about the former, but we can try to fix the latter.

What we are trying to avoid here is: if someone have access to the
database, this person should not be able to send push messages — because
master secret is not there. How? Look at this snippet please:
https://github.com/abstractj/aerogear-unifiedpush-server/commit/a2cb2c6f135aab6d85e1e60e6271ceae445ece1e#diff-9ce4033a33f0606bf0c35537a1fd95bdL84

Previously we had a comparison against the database:

if (pushApplication != null &&
pushApplication.getMasterSecret().equals(secret))

The proposal doesn't store the master secret and makes use of a
derivation function which means: given a salt and a password (master
secret), I was supposed to be able to compute the key for further
comparisons — to check if they match.

Let's see how it works:

1. The server generates a salt and a master secret (111111)
2. The salt is stored into the database. Master secret, not.
3. Given the master secret we compute the key
(https://github.com/abstractj/aerogear-unifiedpush-server/commit/a9993c35edc39501eef7d7a26f3d8ea29b38e293#diff-dc07653bd3c83d4e82c45b70d8ad34dfR177)
4. Store it for further comparisons
5. The following key is generated:
FPj+xcfeoR5vJdi6SsqxiT0WK8cv4PesQ0jpDMYdTYk=

What would happen if someone get access to DB?

1. Evil gets access to the database
2. Manage to retrieve the key: FPj+xcfeoR5vJdi6SsqxiT0WK8cv4PesQ0jpDMYdTYk=
3. Now Evil try to send push messages
4. The following code will attempt to validate:
FPj+xcfeoR5vJdi6SsqxiT0WK8cv4PesQ0jpDMYdTYk= but the password was 111111

You can see the simulation with the following code:

@Test
public void testEvilScenario() throws Exception {
Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
String masterSecret = "111111";
byte[] salt = RandomUtils.randomBytes();
//Master secret is never stored into the database
byte[] applicationSecret = pbkdf2.encrypt(masterSecret);
// Now Evil stole the applicationSecret.
// Providing String pushApplicationID = credentials[0]; String secret =
credentials[1];
// First the is stored in an array of bytes and validate method do not
support byte array as parameter
// No problem, we can attempt to convert to BASE64
String evilMasterSecret = Base64.BASE64.encode(applicationSecret);
//Now lets try to compute the key
assertTrue("Key is not valid", pbkdf2.validate(evilMasterSecret,
applicationSecret, salt));
}

Let me know if you have more questions.








Karel Piwko wrote:
> Still not there.
>
> If we store *secret key* and *salt* in DB, whoever gets access to DB can
> compute derived key via PDKDF2, right?
>
> Is the security increased because hackers need to acquire two values instead of
> one?

--
abstractj



_______________________________________________
aerogear-dev mailing list
aerogear-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/aerogear-dev