我正在尝试在 Android 上使用libsodium加密库(NaCl 的便携式版本(nacl.cr.yp.to)),但我无法弄清楚如何正确编译/使用Kalium-JNI语言绑定。
到目前为止,我已按照 libsodium 网站上的说明成功编译了 libsodium。另外,我使用了 3 天前添加的新的 android-arm 编译脚本。作为测试,我还编译了 android-x86 版本来比较生成的库文件的文件大小。它们不同,所以这似乎有效。作为下一步,我使用新生成的 android-arm libsodium 文件安装了 KaliumJNI。这里没有问题。
在我的小 android-maven 测试应用程序中,它基本上是一个“Hello World”原型,我只是想生成一个新的密钥对:
import org.abstractj.kalium.keys.KeyPair;
KeyPair Alice = new KeyPair();
IntelliJ 成功编译了我的小程序,但是当我尝试在我的模拟器(或我的 Nexus S)上运行它时,它崩溃了。首先它崩溃了,因为它无法找到 kaliumjni 库,所以我将 libtestjni.so(它是由 KaliumJNI 生成的 .so 库)添加到我的项目属性中,从而解决了这个问题。我收到的下一条错误消息告诉我 libtestjni.so 不是 32 位(我运行的是 64 位 Ubuntu 12.04LTS)。我不明白为什么它必须是 32 位,但无论如何我设法设置了一个 32 位 Ubuntu 12.04LTS VM 并再次编译了 android-arm libsodium 和 KaliumJNI 以生成一个 32 位 libtestjni.so 文件。但是当我在我的原始应用程序(在我的 64 位机器上)中使用这个 32 位文件时,我收到以下错误:
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:3823)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View$1.onClick(View.java:3818)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app-lib/IM.CRYPTO-1/libtestjni.so" has unexpected e_machine: 3
at java.lang.Runtime.loadLibrary(Runtime.java:364)
at java.lang.System.loadLibrary(System.java:526)
at org.abstractj.kalium.NaCl.<clinit>(NaCl.java:36)
at org.abstractj.kalium.keys.KeyPair.<init>(KeyPair.java:36)
at IM.CRYPTO.HelloAndroidActivity.buttonClick(HelloAndroidActivity.java:43)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View$1.onClick(View.java:3818)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
我花了几个小时才达到这一点,但现在我不知道我应该从这里去哪里。似乎 e_machine: 3 代表某种架构问题,但我不知道我哪里出错了。该应用程序针对 Android 4.0 (Android API 14) 进行编译,模拟器配置为使用 arm 和相同的 API 14(Nexus 手机运行带有 Android 4.3.1 的 CM)。如前所述,libsodium 也是为 arm 编译的。
更多信息:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>IM.CRYPTO</groupId>
<artifactId>cryptolibAndroid</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>apk</packaging>
<name>cryptolibAndroid</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<platform.version> 4.0.1.2
</platform.version>
<android.plugin.version>3.6.0</android.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>${platform.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.abstractj.kalium</groupId>
<artifactId>kalium-jni</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>${android.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
<attachJar>true</attachJar>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<configuration>
<sdk>
<platform>14</platform>
</sdk>
</configuration>
</plugin>
</plugins>
</build>
氯化钠.java
(这个类被调用来加载testjni(KaliumJNI))
package org.abstractj.kalium;
public class NaCl {
public static Sodium sodium() {
return SingletonHolder.SODIUM_INSTANCE;
}
private static final String LIBRARY_NAME = "sodium";
private static final class SingletonHolder {
public static final Sodium SODIUM_INSTANCE = new Sodium();
}
private NaCl() {
}
static {
System.loadLibrary("testjni");
}
}
我很感激任何提示我指向正确的方向。
请注意,我还有一个小的 JAVA 桌面应用程序,它使用 libsodium + Kalium(不是 KaliumJNI)并且运行没有任何问题。