title: How can I save my keystore securely
body: <p>I have written an API so that my different apps can use it.It simply checks whether app is registered with the server or not.If not then it generates Public/Private keypair,and got a signed certificate by sending CSR to my server. The next time it uses the signed certificate and private key. Initially I have default keystore file in raw ( b/c all my communication is over SSL i.e. initially with default keystore and after registration with user generated keystore)</p>
  
  <p>My API is working fine. The issues I am having are somewhat related to my lack of knowledge or wrong approach and hence I need assistance.</p>
  
  <p>I am using the following class to save/retrieve my Keypair</p>
  
  <pre><code>public class KeyIOHandler {
  
  
      public static void writePublicKeyToPreferences(KeyPair key, Context context) {
          StringWriter publicStringWriter = new StringWriter();
          try {
              PemWriter pemWriter = new PemWriter(publicStringWriter);
              pemWriter.writeObject(new PemObject("myapp.PUBLIC KEY", key.getPublic().getEncoded()));
              pemWriter.flush();
              pemWriter.close();
              SharedPreferences preferences = context.getSharedPreferences("SHARED_PREFERENCES",0);
              preferences.edit().putString("RSA_PUBLIC_KEY", publicStringWriter.toString()).commit();
              Log.e("Public  Key", publicStringWriter.toString());
          } catch (IOException e) {
              Log.e("RSA", e.getMessage());
              e.printStackTrace();
          }
      }
  
      public static void writePrivateKeyToPreferences(KeyPair keyPair, Context context) {
          StringWriter privateStringWriter = new StringWriter();
          try {
              PemWriter pemWriter = new PemWriter(privateStringWriter);
              pemWriter.writeObject(new PemObject("myapp.PRIVATE KEY", keyPair.getPrivate().getEncoded()));
              pemWriter.flush();
              pemWriter.close();
              SharedPreferences preferences = context.getSharedPreferences("SHARED_PREFERENCES",0);
              preferences.edit().putString("RSA_PRIVATE_KEY", privateStringWriter.toString()).commit();
              Log.e("Private Key",privateStringWriter.toString());
          } catch (IOException e) {
              Log.e("RSA", e.getMessage());
              e.printStackTrace();
          }
      }
  
      public static PublicKey getRSAPublicKeyFromString(String publicKeyPEM) throws Exception {
          publicKeyPEM = stripPublicKeyHeaders(publicKeyPEM);
          KeyFactory keyFactory = KeyFactory.getInstance("RSA", "SC");
          byte[] publicKeyBytes = Base64.decode(publicKeyPEM.getBytes("UTF-8"));
          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes);
          return keyFactory.generatePublic(x509KeySpec);
      }
  
      public static PrivateKey getRSAPrivateKeyFromString(String privateKeyPEM) throws Exception {
          privateKeyPEM = stripPrivateKeyHeaders(privateKeyPEM);
          KeyFactory fact = KeyFactory.getInstance("RSA", "SC");
          byte[] clear = Base64.decode(privateKeyPEM);
          PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
          PrivateKey priv = fact.generatePrivate(keySpec);
          Arrays.fill(clear, (byte) 0);
          return priv;
      }
  
      public static String stripPublicKeyHeaders(String key) {
          //strip the headers from the key string
          StringBuilder strippedKey = new StringBuilder();
          String lines[] = key.split("\n");
          for (String line : lines) {
              if (!line.contains("BEGIN PUBLIC KEY") &amp;&amp; !line.contains("END PUBLIC KEY") &amp;&amp; !isNullOrEmpty(line.trim())) {
                  strippedKey.append(line.trim());
              }
          }
          return strippedKey.toString().trim();
      }
  
      public static String stripPrivateKeyHeaders(String key) {
          StringBuilder strippedKey = new StringBuilder();
          String lines[] = key.split("\n");
          for (String line : lines) {
              if (!line.contains("BEGIN PRIVATE KEY") &amp;&amp; !line.contains("END PRIVATE KEY") &amp;&amp; !isNullOrEmpty(line.trim())) {
                  strippedKey.append(line.trim());
              }
          }
          return strippedKey.toString().trim();
      }
  
      public static boolean isNullOrEmpty(String str) {
          return str == null || str.isEmpty();
      }
  }
  </code></pre>
  
  <p>and by using the following method I am generating my keystore but I am confuse how and where I can store this keystore securely so that i can use it for the rest of app's life.(unless key is stolen). As in shared preferences I cannot store any object, so where to save this keystore.Right now I have static keystore object in my class.(which is worst I know but just to make it working i have made it static)</p>
  
  <pre><code>private boolean  addToStore(){
          try {
              Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
              clientPkcs12 = KeyStore.getInstance("PKCS12");
              clientPkcs12.load(null, null);
              clientPkcs12.setKeyEntry("clientCert", keyPair.getPrivate(), "123456".toCharArray(), chain);
          }
          catch(Exception ex){
              Log.e("",ex.getCause().getMessage());
          }
          return false;
      }
  </code></pre>
  
  <p>I have gone through few posts,among them this is noticeable one <a href="http://nelenkov.blogspot.fr/2012/05/storing-application-secrets-in-androids.html" rel="nofollow">nelenkov.blogspot</a> but not getting how can I achieve my target or am I wrong at saving keystore? I mean do I have to create keystore every time? </p>