I am trying to implement ECIES (using BouncyCastle and FlexiProvider) across mobile app and server communication whereby the mobile app will encrypt a data and server will decrypt the same. Now how should I pass the public key of ECIES to the mobile app for encryption.
I see three options for you, each with strengths and weaknesses.
- Use a PKI with some sort of trusted signing authority and validate that the certificate is signed by a trusted signing authority and that it has some identifier in it that should be present for your app to trust. For example, the certificate could have a Subject field embedded within it that has a value of my-really-cool-app.com. If presented with a certificate signed by the trusted authority with the correct Subject field, you trust the certificate and continue with the connection. This would happen every time you connect.
- Use trust on first use. This means, the first time you connect, you accept whatever certificate you are given. On subsequent connections, you only accept connections that present the same certificate. If a new cert is given, you error out or something. This is similar to how SSH is used most often. In SSH the user is presented with the server's public key certificate fingerprint, but my guess is no one checks that and just trusts it the first time. If it ever changes SSH complains.
- You ship your app with the desired public key certificate (or fingerprint) within it. On making a connection, if the certificate has changed, don't continue the connection. This is pinning.