[aerogear-dev] Question around encryption for iOS push certificate passphrase

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

[aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf
Hello,

I started to take a quick look at [1], for a better encryption of the passphrase for all the iOS variants (stored as plaintext ATM). For that I started looking at our neat Pbkdf2 class, from AeroGear-Crypto.

The idea is to store both: the encrypted password + the salt in the database, instead of the plaintext version of the password/passphrase.

Something like here:


This works fine on things like logins:


However, I am afraid it does not work for the iOS passphrase, required to connect to Apple - looks like the library we use requires it in plain text... (due to Apple? Not sure...)


BTW. here is the relevant usage inside of our UnifiedPush Server:


I am now wondering if there is something we can do for [1], in the long run, not now? 

I see the 'java-apns API' supports passing in a java.security.Keystore, but unfortunately I am not sure if there is an impl. of that which is able to deal w/ encrypted passwords or if something like that might even work at all :-/


Greetings,
Matthias


--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Bruno Oliveira
You don’t need a key pair, so I can’t see any good reason to use the KeyStore. If Apple graciously requires the passphrase in plain text we need to do something about it.

PBKDF2 is not only a function to store passwords, but is also possible to generate secret keys. So into your scenarios the solution is:

        Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
        byte[] salt = new Random().randomBytes();
        int iterations = 100000;
        SecretKey secretKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);

        CryptoBox cryptoBox = new CryptoBox(secretKey.getEncoded());
        String passphrase = "My bonnie lies over the ocean";
        byte[] ciphertext = cryptoBox.encrypt(CRYPTOBOX_IV, passphrase, RAW);


Salt, IV and the number of iterations must be stored in some place, or you can just stick with the default number of iterations. But you still need to store salt and IV.

--  
abstractj

On February 5, 2014 at 9:20:37 AM, Matthias Wessendorf ([hidden email]) wrote:
> > However, I am afraid it does not work for the iOS passphrase,  
> required to connect to Apple - looks like the library we use requires  
> it in plain text... (due to Apple? Not sure...)


_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf
Hello Bruno!


On Wed, Feb 5, 2014 at 3:52 PM, Bruno Oliveira <[hidden email]> wrote:
You don’t need a key pair, so I can’t see any good reason to use the KeyStore. If Apple graciously requires the passphrase in plain text we need to do something about it.

PBKDF2 is not only a function to store passwords, but is also possible to generate secret keys. So into your scenarios the solution is:

        Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
        byte[] salt = new Random().randomBytes();
        int iterations = 100000;
        SecretKey secretKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);

        CryptoBox cryptoBox = new CryptoBox(secretKey.getEncoded());
        String passphrase = "My bonnie lies over the ocean";
        byte[] ciphertext = cryptoBox.encrypt(CRYPTOBOX_IV, passphrase, RAW);


Salt, IV and the number of iterations must be stored in some place, or you can just stick with the default number of iterations. But you still need to store salt and IV.


Ah, thanks for the hints. I have a little isolated test case. In there I (potentially) store the privateKey, the IV and the ciphertext in the database.

This basically simulates the case when the "new iOS variant" form has been submitted - so instead of the plain passphrase for the cert, I store the three guys (privateKey, IV, ciphertext):



Later on, I use the pandora :) to decrypt, by leveraging the stored information in the database (privateKey, IV, ciphertext):


Than I get back the 'plaintext' version of the certificate's passphrase, e.g. as byte[] or String:


Greetings,
Matthias


 

--
abstractj

On February 5, 2014 at 9:20:37 AM, Matthias Wessendorf ([hidden email]) wrote:
> > However, I am afraid it does not work for the iOS passphrase,
> required to connect to Apple - looks like the library we use requires
> it in plain text... (due to Apple? Not sure...)




--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Bruno Oliveira
You shouldn’t store your private key, please make use of the suggested code and let me know.

--  
abstractj

On February 5, 2014 at 2:00:45 PM, Matthias Wessendorf ([hidden email]) wrote:
> > Ah, thanks for the hints. I have a little isolated test case.  
> In there I (potentially) store the privateKey, the IV and the  
> ciphertext in the database.


_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf
Hello Bruno,


On Wed, Feb 5, 2014 at 5:05 PM, Bruno Oliveira <[hidden email]> wrote:
You shouldn’t store your private key, please make use of the suggested code and let me know.


OK, not storing the 'private key', but instead I am only storing the IV, salt and ciphertext, right ? 


The following code is basically the (relevant) code behind the web-form when someone creates the logical construct of an iOS variant:


In real I get all the information for the variant (e.g. its name, its description, its certificate file and the passphrase for the certificate), but the above has been limited to the passphrase, as everything else is not so important here :-)

So after that I have basically the following pieces in the database:
* IV
* salt
* ciphertex

instead of the plaintext passphrase for the iOS certs.  



But, now, somewhere later in in the program, I need to do the decryption to get the actual passphrase for the stored Apple-certificate.
However, I don't see how to create the CryptoBox here, as I should not stash the private/secret key, nor do I have access to the previous CryptoBox object



Looks like I am missing something here

-Matthias


 

--
abstractj

On February 5, 2014 at 2:00:45 PM, Matthias Wessendorf ([hidden email]) wrote:
> > Ah, thanks for the hints. I have a little isolated test case.
> In there I (potentially) store the privateKey, the IV and the
> ciphertext in the database.




--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Daniel Passos-2
On Wed, Feb 5, 2014 at 2:49 PM, Matthias Wessendorf <[hidden email]> wrote:
Hello Bruno,


On Wed, Feb 5, 2014 at 5:05 PM, Bruno Oliveira <[hidden email]> wrote:
You shouldn’t store your private key, please make use of the suggested code and let me know.


OK, not storing the 'private key', but instead I am only storing the IV, salt and ciphertext, right ? 

Right. In this case you don't need store Private Key
 
The following code is basically the (relevant) code behind the web-form when someone creates the logical construct of an iOS variant:


In real I get all the information for the variant (e.g. its name, its description, its certificate file and the passphrase for the certificate), but the above has been limited to the passphrase, as everything else is not so important here :-)

So after that I have basically the following pieces in the database:
* IV
* salt
* ciphertex

instead of the plaintext passphrase for the iOS certs.  

NEVER store password/passphrase
 
But, now, somewhere later in in the program, I need to do the decryption to get the actual passphrase for the stored Apple-certificate.
However, I don't see how to create the CryptoBox here, as I should not stash the private/secret key, nor do I have access to the previous CryptoBox object



Looks like I am missing something here

If you have Salt and password you can create a PrivateKey "on the fly"

Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
byte[] rawPassword = pbkdf2.encrypt(passphrase, salt);
PrivateKey privateKey = new PrivateKey(rawPassword);
 
And for create CriptoBox you only need a PrivateKey

CryptoBox cryptoBox = new CryptoBox(privateKey);

Now you a able to decrypt using stored IV :)

byte[] decryptedData = cryptoBox.decrypt(IV, data);
-Matthias

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf



On Wed, Feb 5, 2014 at 6:53 PM, Daniel Passos <[hidden email]> wrote:
On Wed, Feb 5, 2014 at 2:49 PM, Matthias Wessendorf <[hidden email]> wrote:
Hello Bruno,


On Wed, Feb 5, 2014 at 5:05 PM, Bruno Oliveira <[hidden email]> wrote:
You shouldn’t store your private key, please make use of the suggested code and let me know.


OK, not storing the 'private key', but instead I am only storing the IV, salt and ciphertext, right ? 

Right. In this case you don't need store Private Key
 
The following code is basically the (relevant) code behind the web-form when someone creates the logical construct of an iOS variant:


In real I get all the information for the variant (e.g. its name, its description, its certificate file and the passphrase for the certificate), but the above has been limited to the passphrase, as everything else is not so important here :-)

So after that I have basically the following pieces in the database:
* IV
* salt
* ciphertex

instead of the plaintext passphrase for the iOS certs.  

NEVER store password/passphrase

yep, that's why I am thinking about:

 
 
But, now, somewhere later in in the program, I need to do the decryption to get the actual passphrase for the stored Apple-certificate.
However, I don't see how to create the CryptoBox here, as I should not stash the private/secret key, nor do I have access to the previous CryptoBox object



Looks like I am missing something here

If you have Salt and password you can create a PrivateKey "on the fly"

As said in the comments of I don't have access to the password/passphrase:

 

Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
byte[] rawPassword = pbkdf2.encrypt(passphrase, salt);
PrivateKey privateKey = new PrivateKey(rawPassword);
 
And for create CriptoBox you only need a PrivateKey

CryptoBox cryptoBox = new CryptoBox(privateKey);

Now you a able to decrypt using stored IV :)

byte[] decryptedData = cryptoBox.decrypt(IV, data);
-Matthias

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev



--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Bruno Oliveira
You need tho reconstruct that key again with the pieces from your database, so your code would look like:

@Test
    public void testPasswordValidationWithRandomSaltProvided() throws Exception {
        Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
        byte[] salt = new Random().randomBytes();
        byte[] IV = new Random().randomBytes();
        int iterations = 100000;

        //Encrypt step
        SecretKey secretKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
        CryptoBox box1 = new CryptoBox(secretKey.getEncoded());
        String passphrase = "My bonnie lies over the ocean";
        byte[] ciphertext = box1.encrypt(IV, passphrase.getBytes());

        //Decrypt step
        SecretKey recoveredKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
        CryptoBox box2 = new CryptoBox(recoveredKey.getEncoded());
        byte[] plaintext = box2.decrypt(IV, ciphertext);
        System.out.println(RAW.encode(plaintext));

    }

--  
abstractj

On February 5, 2014 at 3:59:06 PM, Matthias Wessendorf ([hidden email]) wrote:

> > But, now, somewhere later in in the program, I need to do the decryption  
> to get the actual passphrase for the stored Apple-certificate.  
> However, I don't see how to create the CryptoBox here, as I should  
> not stash the private/secret key, nor do I have access to the previous  
> CryptoBox object
>  
> https://github.com/matzew/psswd-salting/blob/master/src/test/java/net/wessendorf/salt/SecretKeyTest.java#L64-L85 
>  
>  
> Looks like I am missing something here


_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf



On Wed, Feb 5, 2014 at 7:41 PM, Bruno Oliveira <[hidden email]> wrote:
You need tho reconstruct that key again with the pieces from your database, so your code would look like:

@Test
    public void testPasswordValidationWithRandomSaltProvided() throws Exception {
        Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
        byte[] salt = new Random().randomBytes();
        byte[] IV = new Random().randomBytes();
        int iterations = 100000;

        //Encrypt step
        SecretKey secretKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
        CryptoBox box1 = new CryptoBox(secretKey.getEncoded());
        String passphrase = "My bonnie lies over the ocean";
        byte[] ciphertext = box1.encrypt(IV, passphrase.getBytes());

        //Decrypt step
        SecretKey recoveredKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);


as said in the comments, I don't have that PASSWORD here


That is only submitted when the user creates a new iOS variant, it's never entered when the server tries to connect to the APNs




 
        CryptoBox box2 = new CryptoBox(recoveredKey.getEncoded());
        byte[] plaintext = box2.decrypt(IV, ciphertext);
        System.out.println(RAW.encode(plaintext));

    }

--
abstractj

On February 5, 2014 at 3:59:06 PM, Matthias Wessendorf ([hidden email]) wrote:
> > But, now, somewhere later in in the program, I need to do the decryption
> to get the actual passphrase for the stored Apple-certificate.
> However, I don't see how to create the CryptoBox here, as I should
> not stash the private/secret key, nor do I have access to the previous
> CryptoBox object
>
> https://github.com/matzew/psswd-salting/blob/master/src/test/java/net/wessendorf/salt/SecretKeyTest.java#L64-L85
>
>
> Looks like I am missing something here




--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Bruno Oliveira
There is no magic, the password must exist in some place. If not possible require the password, is possible to follow the same approach provided for password reset functionality.

If you want to stick to the KeyStore, you still need to provide the password in some place, but that’s more suitable when you have a key exchange or something like this.

So if you patiently read my the code proposed, you will realize that is possible to achieve it via property file, database or whatever:

@Test
    public void testPasswordValidationWithRandomSaltProvided() throws Exception {
        Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
        byte[] salt = new Random().randomBytes();
        byte[] IV = new Random().randomBytes();
        int iterations = 100000;
               
        read.secretFile(“secret.properties”);
        String PASSWORD = read.load(“password_to_my_superpassphrase”);

        //Encrypt step
        SecretKey secretKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
        CryptoBox box1 = new CryptoBox(secretKey.getEncoded());
        String passphrase = "My bonnie lies over the ocean";
        byte[] ciphertext = box1.encrypt(IV, passphrase.getBytes());

        //Decrypt step
        SecretKey recoveredKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
}

If it’s not clear, let me know where should I introduce this functionality rather than a pet project and I can do that.

--  
abstractj

On February 5, 2014 at 4:47:04 PM, Matthias Wessendorf ([hidden email]) wrote:
> > as said in the comments, I don't have that PASSWORD here
>  
>  
> That is only submitted when the user creates a new iOS variant,  
> it's never entered when the server tries to connect to the APNs  


_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf



On Wed, Feb 5, 2014 at 8:00 PM, Bruno Oliveira <[hidden email]> wrote:
There is no magic, the password must exist in some place. If not possible require the password, is possible to follow the same approach provided for password reset functionality.

If you want to stick to the KeyStore, you still need to provide the password in some place, but that’s more suitable when you have a key exchange or something like this.

So if you patiently read my the code proposed, you will realize that is possible to achieve it via property file, database or whatever:

@Test
    public void testPasswordValidationWithRandomSaltProvided() throws Exception {
        Pbkdf2 pbkdf2 = AeroGearCrypto.pbkdf2();
        byte[] salt = new Random().randomBytes();
        byte[] IV = new Random().randomBytes();
        int iterations = 100000;

        read.secretFile(“secret.properties”);
        String PASSWORD = read.load(“password_to_my_superpassphrase”);


yeah, but that is really per variant, not global. So we would need a lot of these secret file :-) 



So, the passphrase is upload to the server (for all iOS variants), w/ this HTTP request:



Somewhen later a totally different system submits a HTTP request to trigger the PUSH message delivery:

And internally, only for iOS variant, all it needs is the certificate (from the apple developer portal) + its passphrase

Perhaps I am wrong, but I feel that if (for iOS variants) we start to require "password_to_my_superpassphrase" on the request for creating the logical construct of the variant,
and use the same for the Sender, we would have that magical password, but I fear that this opens a new can of worms.

 

        //Encrypt step
        SecretKey secretKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
        CryptoBox box1 = new CryptoBox(secretKey.getEncoded());
        String passphrase = "My bonnie lies over the ocean";
        byte[] ciphertext = box1.encrypt(IV, passphrase.getBytes());

        //Decrypt step
        SecretKey recoveredKey = pbkdf2.generateSecretKey(PASSWORD, salt, iterations);
}

If it’s not clear, let me know where should I introduce this functionality rather than a pet project and I can do that.


The AGPUSH-358 ticket is still yours :-) I just felt looking at it, while reading up on our crypto bits.

 

--
abstractj

On February 5, 2014 at 4:47:04 PM, Matthias Wessendorf ([hidden email]) wrote:
> > as said in the comments, I don't have that PASSWORD here
>
>
> That is only submitted when the user creates a new iOS variant,
> it's never entered when the server tries to connect to the APNs




--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Bruno Oliveira
On February 5, 2014 at 5:47:24 PM, Matthias Wessendorf ([hidden email]) wrote:
> > yeah, but that is really per variant, not global. So we would  
> need a lot of these secret file :-)

You’ve probably misunderstood what I said, but that would be silly and impractical, I didn’t say that, right? If you don’t want to require an input every time, make use of SINGLE key to encrypt the passphrases that’s what was suggested.

>  
>
>  
> Perhaps I am wrong, but I feel that if (for iOS variants) we start  
> to require "password_to_my_superpassphrase" on the request  
> for creating the logical construct of the variant,
> and use the same for the Sender, we would have that magical password, 

That’s what I’ve already mentioned, the password MUST be provided. And there are a gazillion of solutions to the same problem outside there.

> but I fear that this opens a new can of worms.

Why?

>  
>  
> The AGPUSH-358 ticket is still yours :-) I just felt looking at  
> it, while reading up on our crypto bits.

I don’t bother whoever will solve this ticket. If you want to jump in, feel free to reassign to you, if don’t I can look at this on the next week.

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Matthias Wessendorf



On Wed, Feb 5, 2014 at 9:02 PM, Bruno Oliveira <[hidden email]> wrote:
On February 5, 2014 at 5:47:24 PM, Matthias Wessendorf ([hidden email]) wrote:
> > yeah, but that is really per variant, not global. So we would
> need a lot of these secret file :-)

You’ve probably misunderstood what I said, but that would be silly and impractical, I didn’t say that, right? If you don’t want to require an input every time, make use of SINGLE key to encrypt the passphrases that’s what was suggested.

>
>
>
> Perhaps I am wrong, but I feel that if (for iOS variants) we start
> to require "password_to_my_superpassphrase" on the request
> for creating the logical construct of the variant,
> and use the same for the Sender, we would have that magical password, 

That’s what I’ve already mentioned, the password MUST be provided. And there are a gazillion of solutions to the same problem outside there.

> but I fear that this opens a new can of worms.

Why?

isn't is a problem if  some backend app has to store this password as well? In order to have their batch system (or what ever) being able to trigger push message delivery ? 
 

>
>
> The AGPUSH-358 ticket is still yours :-) I just felt looking at
> it, while reading up on our crypto bits.

I don’t bother whoever will solve this ticket. If you want to jump in, feel free to reassign to you, if don’t I can look at this on the next week.



--
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
qmx
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

qmx
Administrator
On Wed, Feb 05, 2014 at 09:06:04PM +0100, Matthias Wessendorf wrote:
> isn't is a problem if  some backend app has to store this password as well?
> In order to have their batch system (or what ever) being able to trigger
> push message delivery ?

Well, there's no free lunch, you've got to store this somewhere - or
shoot for oauth dance between apps + HSMs + loads of money

--
qmx
_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev
Reply | Threaded
Open this post in threaded view
|

Re: [aerogear-dev] Question around encryption for iOS push certificate passphrase

Bruno Oliveira
+1

--
abstractj

On February 5, 2014 at 6:13:31 PM, Douglas Campos ([hidden email]) wrote:
> > Well, there's no free lunch, you've got to store this somewhere
> - or
> shoot for oauth dance between apps + HSMs + loads of money

_______________________________________________
aerogear-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/aerogear-dev