【问题标题】:Xamarin.Android binding Spongy Castle / Bouncy CastleXamarin.Android 绑定 Spongy Castle / Bouncy Castle
【发布时间】:2016-07-01 13:57:38
【问题描述】:

任何人成功地将SpongyCastle 绑定到 Xamarin.Android?我在绑定项目中的 Metadata.xml 遇到了一堆警告。

到目前为止我有:

<remove-node path="/api/package[@name='org.spongycastle.x509']" />
<remove-node path="/api/package[@name='org.spongycastle.crypto']" />
<remove-node path="/api/package[@name='org.spongycastle.crypto.tls']" />
<remove-node path="/api/package[@name='org.spongycastle.cms']" />
<remove-node path="/api/package[@name='org.spongycastle.crypto.prng']" />
<remove-node path="/api/package[@name='org.spongycastle.openpgp']" />
<remove-node path="/api/package[@name='org.spongycastle.openssl']" />
<remove-node path="/api/package[@name='org.spongycastle.cert.ocsp']" />

<remove-node path="/api/package[@name='org.spongycastle.jcajce']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.dh']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.ec']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.digest']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.keystore.bc']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.symmetric']" />

<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.dsa']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.util']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.symmetric.util']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.gost']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.ies']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.rsa']" />
<remove-node path="/api/package[@name='org.spongycastle.jcajce.provider.asymmetric.x509']" />

<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='CertStoreCollectionSpi']" />
<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='MultiCertStoreSpi']" />
<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='X509CRLEntryObject']" />
<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='X509CRLObject']" />
<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='X509CertificateObject']" />
<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='X509LDAPCertStoreSpi']"/>
<remove-node path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='PKIXPolicyNode']" />

<remove-node path="/api/package[@name='org.spongycastle.pqc.jcajce.provider.rainbow']" />
<remove-node path="/api/package[@name='org.spongycastle.pqc.jcajce.provider.mceliece']"/>
<remove-node path="/api/package[@name='org.spongycastle.pqc.jcajce.provider.util']" />
<remove-node path="/api/package[@name='org.spongycastle.pqc.crypto.ntru']" />
<remove-node path="/api/package[@name='org.spongycastle.pqc.math.ntru.polynomial']" />

所以它可以编译,但是在 Xamarin.Android 项目中使用绑定项目时需要几分钟。编译,然后抱怨 Java 的 HEAP 大小失败。

当我将堆大小设置为 1GB 时,它会完成,但是当在设备上以调试模式运行应用程序时,调试会中断。

有没有办法在没有绑定库的情况下只使用 ARR?我只需要调用我在此 ARR 中创建的包装器方法并从中获取输出。我不需要通过 C# 访问完整的库。还是有更好的办法?

更新: 当我构建 CPU 时,看起来像这样(看 Java):

【问题讨论】:

  • 为什么不使用充气城堡?
  • 我不是加密专家,但是当各种论坛上有这么多人说:“不幸的是,Android 平台发布了一个不完整且过时的 Android 版 Bouncy Castle,这也使得安装更新的“ - 我选择海绵城堡。参考:aerogear.org/docs/specs/aerogear-crypto
  • 最近我在 Android 的 pcl 中使用了充气城堡。没问题。
  • 这可能取决于您需要做什么。我依赖于几个库,它们用 NFC 做了一些非常好的事情。因此,建议通过我所依赖的库来使用 SpongyCastle。无论如何,这更多的是解决从 Xamarin 到 Java 的绑定/调用,而不是需要什么样的库。

标签: android xamarin xamarin.android bouncycastle spongycastle


【解决方案1】:

ARR 是指AAR 吗?在只使用部分物品的情况下,可以直接使用JNIhttps://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/working_with_jni/

最简单的方法是 &lt;remove-node&gt; 在您不想保留的所有项目中处理您想要保留的项目。但是,您可能需要确保保留依赖项,以便它们正确绑定。这很快就会变得很糟糕。

我有一个通用指南,可能在此绑定的某些领域有所帮助:

https://github.com/JonDouglas/xamarin-support-docs/blob/master/Android/android-bindings-troubleshooting.md

正如@jzeferino 所提到的,你总是可以选择使用比自己绑定绑定更久经考验的东西。

BouncyCastle-PCL:https://github.com/onovotny/BouncyCastle-PCL

PCL 加密:https://github.com/AArnott/PCLCrypto

这两种方法都提供了各自的加密方法来完成您的任务。对于 PCLCrypto,它们要么由 Mono 的实现提供,要么由平台的实现提供。

【讨论】:

  • @chrisva 我认为这是最好的选择,这就是我说搬到充气城堡的原因。
  • 是的,我的意思是 AAR。感谢您向我指出已经存在的 PCL 的方向。我很了解他们。我的第 3 方库依赖于 Spongy Castle,所以我不是在寻找一种简单的方法来解决它。我想学习如何以最优化的方式进行绑定,因为我们构建的内容将来需要一些具有各种复杂性的绑定项目。所以在这种情况下,JNI 对我们来说似乎是一种非常有趣的方法。我将深入研究它并提供最新进展。谢谢。
  • 顺便说一句,该指南很棒@jon-douglas
【解决方案2】:

我最终在绑定项目的 metadata.xml 文件中删除了与 BouncyCastle 和 SpongyCastle 相关的几乎所有内容。然后我从 Binding Project 的生成文件夹中复制了部分生成的 BouncyCastleProvider。所以我只为我需要调用的部分创建了自己的 JNI 包装器。

效果很好。现在编译时间减少到几秒钟,并且在调试过程中部署速度很快。我喜欢第三方库。

我的想法是首先生成 C# 类,然后选择在我自己的库中实现部分 JNI 并在 Metadata.xml 中添加/删除节点。

using System;
using System.Collections.Generic;
using Android.Runtime;
namespace Org.Spongycastle.Jce.Provider
{

// Metadata.xml XPath class reference: path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='BouncyCastleProvider']"
[global::Android.Runtime.Register("org/spongycastle/jce/provider/BouncyCastleProvider", DoNotGenerateAcw = true)]
public sealed partial class BouncyCastleProvider : global::Java.Security.Provider
{
    // Metadata.xml XPath field reference: path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='BouncyCastleProvider']/field[@name='PROVIDER_NAME']"
    [Register("PROVIDER_NAME")]
    public const string ProviderName = (string)"SC";

    internal static IntPtr java_class_handle;
    internal static IntPtr class_ref
    {
        get
        {
            return JNIEnv.FindClass("org/spongycastle/jce/provider/BouncyCastleProvider", ref java_class_handle);
        }
    }

    protected override IntPtr ThresholdClass
    {
        get { return class_ref; }
    }

    protected override global::System.Type ThresholdType
    {
        get { return typeof(BouncyCastleProvider); }
    }

    internal BouncyCastleProvider(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { }

    static IntPtr id_ctor;
    // Metadata.xml XPath constructor reference: path="/api/package[@name='org.spongycastle.jce.provider']/class[@name='BouncyCastleProvider']/constructor[@name='BouncyCastleProvider' and count(parameter)=0]"
    [Register(".ctor", "()V", "")]
    public unsafe BouncyCastleProvider()
        : base(IntPtr.Zero, JniHandleOwnership.DoNotTransfer)
    {
        if (Handle != IntPtr.Zero)
            return;

        try
        {
            if (GetType() != typeof(BouncyCastleProvider))
            {
                SetHandle(
                        global::Android.Runtime.JNIEnv.StartCreateInstance(GetType(), "()V"),
                        JniHandleOwnership.TransferLocalRef);
                global::Android.Runtime.JNIEnv.FinishCreateInstance(Handle, "()V");
                return;
            }

            if (id_ctor == IntPtr.Zero)
                id_ctor = JNIEnv.GetMethodID(class_ref, "<init>", "()V");
            SetHandle(
                    global::Android.Runtime.JNIEnv.StartCreateInstance(class_ref, id_ctor),
                    JniHandleOwnership.TransferLocalRef);
            JNIEnv.FinishCreateInstance(Handle, class_ref, id_ctor);
        }
        finally
        {
        }
    }
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    相关资源
    最近更新 更多