android 的 Facebook 隐藏加密始终不可用
Facebook Conceal crypto for android is always unavailable
我无法在我的 android 应用程序中使用 Facebook Conceal 库。 crypto
在 crypto.isAvailable()
上似乎总是 return 正确。
此外,我使用的 Android 1.0.2 没有明确列出所包含的库,但我已将其放在正确的 libs 文件夹中。
我包含了上一个 link 中可用的 Jar 和本机二进制文件。 .zip 文件包含在构建中:
compile fileTree(dir: 'libs', include: ['*.jar', '*.zip'])
构建似乎有效。我验证了本机库:cryptox.so
和 conceal.so
包含在 apk/libs 中,而其他包含 com.facebook.crypto
等包的 jar 二进制文件包含在 classes.dex
中。
以下是activity代码:
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);
}
// 下面的第一个条件总是满足意味着库没有正确加载。
// 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();
}
}
我不确定库或代码是否有问题。
在 jar 中,代码似乎在
中失败
com.facebook.crypto.util.SystemNativeCryptoLibrary.java
private static final ArrayList<String> LIBS = new ArrayList<String>() {{
add("cryptox");
add("conceal");
}};
// 在执行下面这一段时抛出 java.lang.UnsatisfiedLinkError 异常:
for (String name : LIBS) {
System.loadLibrary(name);
Assaf's solution 是有效的。
下面是库需要进入的结构。
项目:
|--库:
|--|--armeabi:
|--|--|--.so 文件。
请注意,下载的 libs.zip
中的所有库文件都压缩在 libs
根文件夹中,需要将其更改为 lib
以便将库正确捆绑在 .apk
你可以尝试将.so文件相应地放到/app/src/main/jniLibs/下。
app
+-src
+-main
+-jniLibs
+-armeabi
| +-libconceal.so
+-armeabi-v7a
| +-libconceal.so
+-mips
+-x86
+-libconceal.so
我无法在我的 android 应用程序中使用 Facebook Conceal 库。 crypto
在 crypto.isAvailable()
上似乎总是 return 正确。
此外,我使用的 Android 1.0.2 没有明确列出所包含的库,但我已将其放在正确的 libs 文件夹中。
我包含了上一个 link 中可用的 Jar 和本机二进制文件。 .zip 文件包含在构建中:
compile fileTree(dir: 'libs', include: ['*.jar', '*.zip'])
构建似乎有效。我验证了本机库:cryptox.so
和 conceal.so
包含在 apk/libs 中,而其他包含 com.facebook.crypto
等包的 jar 二进制文件包含在 classes.dex
中。
以下是activity代码:
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);
}
// 下面的第一个条件总是满足意味着库没有正确加载。
// 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();
}
}
我不确定库或代码是否有问题。
在 jar 中,代码似乎在
中失败com.facebook.crypto.util.SystemNativeCryptoLibrary.java
private static final ArrayList<String> LIBS = new ArrayList<String>() {{
add("cryptox");
add("conceal");
}};
// 在执行下面这一段时抛出 java.lang.UnsatisfiedLinkError 异常:
for (String name : LIBS) {
System.loadLibrary(name);
Assaf's solution 是有效的。
下面是库需要进入的结构。
项目:
|--库:
|--|--armeabi:
|--|--|--.so 文件。
请注意,下载的 libs.zip
中的所有库文件都压缩在 libs
根文件夹中,需要将其更改为 lib
以便将库正确捆绑在 .apk
你可以尝试将.so文件相应地放到/app/src/main/jniLibs/下。
app
+-src
+-main
+-jniLibs
+-armeabi
| +-libconceal.so
+-armeabi-v7a
| +-libconceal.so
+-mips
+-x86
+-libconceal.so