Problem beim Übergeben von Byte [] über jni an C unter Android

8

Ich habe ein byte[] in Java, das seine Länge als 256 Bytes angibt, die ich an eine native Funktion in C übergebe.

Als ich versuchte, die Daten aus diesem Array zu bekommen, war es völlig falsch und als ich es ausgedruckt hatte, stimmte es nicht mit den Daten überein, die ich ausgedruckt hatte, bevor ich es an C übergeben habe.

Ich habe einige Möglichkeiten ausprobiert, um auf die Daten einschließlich GetByteArrayRegion und GetByteArrayElements zuzugreifen, aber nichts scheint mir die Daten zu geben, die ich erwarte.

Als ich dies untersuchte, versuchte ich zu sehen, was JNI für die jbyteArray -Länge hielt mit GetArrayLength - es gab die Länge als 1079142960 an, weit mehr als die erwarteten 256 Bytes. Auch der Wert war bei jedem Aufruf der Funktion unterschiedlich, zB eine andere Zeit GetArrayLength gab 1079145720 zurück.

Hier ist der Code, mit dem ich auf das Array zugreife:

%Vor%

Das scheint ziemlich geradlinig zu sein, also bin ich mir nicht wirklich sicher, was los ist. Das Array scheint von Java in Ordnung zu sein, aber es wurde in C generiert und zurückgegeben, also nehme ich an, dass dort etwas schief gelaufen ist, das Java nicht interessiert, aber das Array bricht, wenn es zu C zurückkehrt.

Hier ist der Code, den ich verwendet habe, um das Array zu generieren und es an Java zurück zu geben:

%Vor%

Vermisse ich etwas?

Danke

    
Carl Minden 13.08.2011, 08:44
quelle

3 Antworten

12

Dieser Funktionsprototyp ist falsch:

%Vor%

Das zweite Argument ist entweder ein jclass oder ein jobject . Wenn Ihre Methode statisch ist, sollte es sein:

%Vor%

Und wenn es nicht statisch ist:

%Vor%

Sie behandeln die Klasse oder das Objekt als ein Array, das die unerwarteten Ergebnisse erklärt, die Sie erhalten.

    
olivierg 13.08.2011, 11:52
quelle
1

Ich nehme an, dass das Hauptproblem darin besteht, dass Sie eine OpenSSL-Struktur in ein Byte-Array erzwingen. Wahrscheinlich wird diese Struktur im Laufe der Zeit freigegeben werden. Das würde die seltsamen und unterschiedlichen Längen erklären, die dir zurückgemeldet werden, wenn du zu C zurückkehrst. Ein RSA* zu Java zu bringen, wird dir auch nicht sehr helfen - Java hat kein Wissen über diese bestimmte Struktur und wird es nicht können erkenne es.

Was Sie ausprobieren sollten, ist eines von

  • i2d_PKCS8PrivateKey_bio (BIO * bp, EVP_PKEY * x, const EVP_CIPHER * enc, char * kstr, int klen, pem_password_cb * cb, void * u)
  • int i2d_RSA_PUBKEY (RSA * a, unsigniertes Zeichen ** pp)

je nachdem, ob Sie nur die öffentlichen Schlüsselinformationen oder auch die privaten Informationen an Java übergeben möchten ( siehe auch hier) ). Auf diese Weise können Sie sicher sein, von Anfang an mit einem Byte-Array zu arbeiten.

Sobald dies für Sie funktioniert (mit den Techniken, die Sie bereits ausprobiert haben), können Sie in Java das Byte-Array in etwas Sinnvolles parsen. Dies ist im Fall des öffentlichen Schlüssels sehr einfach: Verwenden Sie X509EncodedKeySpec mit Ihrem Array und erzeugen Sie einen öffentlichen Schlüssel mit KeyFactory # generatePublic .

Im privaten Schlüsselfall sind die Dinge etwas komplizierter. Java versteht nur das PKCS # 8-Format , während OpenSSL es codiert private RSA-Schlüssel gemäß dem PKCS # 1-Format standardmäßig. Sie können Ihren Schlüssel jedoch bereits mit i2d_PKCS8PrivateKey_bio in PKCS # 8 konvertieren. Sie müssen jedoch Ihre RSA* zuerst als EVP_PKEY* einpacken:

%Vor%

Verschlüsseln Sie Ihren Schlüssel nicht und verwenden Sie eine speicherinterne BIO , und übergeben Sie dann die Ergebnis Byte Array zu Java und dort zu dem Konstruktor von PKCS8EncodedKeySpec und schließlich generieren Sie Ihren privaten Schlüssel mit dem KeyFactory .

    
emboss 13.08.2011 11:28
quelle
0

Versuchen Sie, die Zeichenfolge mit dem Zeichen "\ 0" anzufügen. Wahrscheinlich ist es nicht in der Lage, das Ende der Zeichenfolge zu identifizieren.

    
Ronnie 13.08.2011 09:09
quelle

Tags und Links