I'm not able to use Facebook Conceal Libraries in my android application. The crypto
always seems to return true on crypto.isAvailable()
.
Also, I'm using Android 1.0.2 that does not explicitly lists the libraries included, but I've put it in the correct libs folder.
I included the Jar and Native Binaries available on the previous link. The .zip file was included in the build as:
compile fileTree(dir: 'libs', include: ['*.jar', '*.zip'])
The build seem to work. I verified that the native libraries: cryptox.so
and conceal.so
are included in apk/libs, and the other jar binary with packages like com.facebook.crypto
is included within classes.dex
.
Following is the activity 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);
}
// The first condition below is always satisfied meaning the library isn't loaded correctly.
// 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();
}
}
I'm not sure whether there's some issue with the library or the code.
Inside the jar, it seems like the code is failing in
com.facebook.crypto.util.SystemNativeCryptoLibrary.java
private static final ArrayList<String> LIBS = new ArrayList<String>() {{
add("cryptox");
add("conceal");
}};
// It throws a java.lang.UnsatisfiedLinkError exception while executing this piece below:
for (String name : LIBS) {
System.loadLibrary(name);