title: Facebook Conceal crypto for android is always unavailable
body: <p>I'm not able to use <a href="https://facebook.github.io/conceal/documentation/" rel="nofollow">Facebook Conceal</a> Libraries in my android application. The <code>crypto</code> always seems to return true on <code>crypto.isAvailable()</code>.
  Also, I'm using Android 1.0.2 that does not explicitly lists the libraries included, but I've put it in the correct <strong>libs</strong> folder. </p>
  
  <p>I included the Jar and Native Binaries available on the previous link. The .zip file was included in the build as:</p>
  
  <pre><code>compile fileTree(dir: 'libs', include: ['*.jar', '*.zip'])
  </code></pre>
  
  <p>The build seem to work. I verified that the native libraries: <code>cryptox.so</code> and <code>conceal.so</code> are included in apk/libs, and the other jar binary with packages like <code>com.facebook.crypto</code> is included within <code>classes.dex</code>. </p>
  
  <p>Following is the activity code:</p>
  
  <pre><code>import com.facebook.crypto.Crypto;
  import com.facebook.crypto.Entity;
  import com.facebook.crypto.keychain.SharedPrefsBackedKeyChain;
  import com.facebook.crypto.util.SystemNativeCryptoLibrary;
  
  public class ConcealActivity extends Activity implements View.OnClickListener {
  public static String filename = "data.txt";
  public static String filepath = "concealedata";
  public static String TAG = "com.zing.ConcealActivity";
  File myInternalFile;
  Crypto crypto;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_conceal);
  
      Log.i(TAG, "created method.");
      ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext());
      File directory = contextWrapper.getDir(filepath, Context.MODE_PRIVATE);
      myInternalFile = new File(directory, filename);
      crypto = new Crypto(new SharedPrefsBackedKeyChain(this), new SystemNativeCryptoLibrary());
      Button cencrypt = (Button) findViewById(R.id.cencrypt);
      cencrypt.setOnClickListener(this);
  
      Button cdecrypt = (Button) findViewById(R.id.cdecrypt);
      cdecrypt.setOnClickListener(this);
  }
  
  @Override
  public void onClick(View v) {
      Log.i(TAG, "onclick method.");
      EditText myInputText = (EditText) findViewById(R.id.inputText);
      TextView responseText = (TextView) findViewById(R.id.responseText);
      String myData = "";
  
      switch (v.getId()) {
          case R.id.cencrypt:
              encryptandsave(myInputText.getText().toString().getBytes());
              myInputText.setText("");
              responseText.setText(readFile(myInternalFile));
              break;
  
          case R.id.cdecrypt:
              responseText.setText(readanddecrypt());
              break;
      }
  }
  
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.menu_conceal, menu);
      return true;
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar will
      // automatically handle clicks on the Home/Up button, so long
      // as you specify a parent activity in AndroidManifest.xml.
      int id = item.getItemId();
  
      //noinspection SimplifiableIfStatement
      if (id == R.id.action_settings) {
          return true;
      }
  
      return super.onOptionsItemSelected(item);
  }
  </code></pre>
  
  <p>// The first condition below is always satisfied meaning the library isn't loaded correctly.</p>
  
  <pre><code>// Encrypts the data and saves to directory
  public void encryptandsave(byte[] plainTextBytes) {
      try {
      // Check for whether the crypto functionality is available
      // This might fail if android does not load libaries correctly.
          if (!crypto.isAvailable()) {
              Log.e(TAG, "Cipher unavailable.");
              return;
          }
  
          OutputStream fileStream = new BufferedOutputStream(new FileOutputStream(myInternalFile));
          OutputStream outputStream = crypto.getCipherOutputStream(fileStream, new Entity("Password"));
          outputStream.write(plainTextBytes);
          outputStream.close();
      } catch (Exception e) {
          Log.e(TAG, "EXCEPTION encryptandsave: " + e.getMessage());
      }
  }
  
  // decode encrypted file and returns Bitmap
  private String readanddecrypt() {
      try {
          if (!crypto.isAvailable()) {
              Log.e(TAG, "Cipher unavailable.");
              return "";
          }
          FileInputStream fileStream = new FileInputStream(filename);
          InputStream inputStream = crypto.getCipherInputStream(fileStream, new Entity("Password"));
          ByteArrayOutputStream out = new ByteArrayOutputStream();
  
          int read;
          byte[] buffer = new byte[1024];
          while ((read = inputStream.read(buffer)) != -1) {
              out.write(buffer, 0, read);
          }
          inputStream.close();
          return out.toString();
      } catch (Exception e) {
          Log.e(TAG, "EXCEPTION readanddecrypt: " + e.getMessage());
      }
      return null;
  }
  
  public String readFile(File internalFile) {
      StringBuilder sb = new StringBuilder();
      try {
          FileInputStream fis = new FileInputStream(internalFile);
          DataInputStream in = new DataInputStream(fis);
          BufferedReader br = new BufferedReader(new InputStreamReader(in));
          String strLine;
          while ((strLine = br.readLine()) != null) {
              sb.append(strLine);
          }
          in.close();
      } catch (IOException e) {
          Log.e(TAG, "EXCEPTION readFile: " + e.getMessage());
          return "";
      }
      return sb.toString();
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I'm not sure whether there's some issue with the library or the code.</p>
  
  <p>Inside the jar, it seems like the code is failing in </p>
  
  <pre><code>com.facebook.crypto.util.SystemNativeCryptoLibrary.java
  
  private static final ArrayList&lt;String&gt; LIBS = new ArrayList&lt;String&gt;() {{
    add("cryptox");
    add("conceal");
  }};
  </code></pre>
  
  <p>// It throws a java.lang.UnsatisfiedLinkError exception while executing this piece below:</p>
  
  <pre><code>for (String name : LIBS) {
    System.loadLibrary(name);
  </code></pre>