1.9k Aufrufe
Gefragt in Anwendungen(Java,C++...) von mixmax Experte (2.2k Punkte)
Nun ich sitze schon seit mehreren Tagen an diesem Problem und vermutlich bin ich etwas Betriebsblind geworden.

mit dem Programmcode den ich hier Poste teste ich ein ver und entschlüsselung von einem 320 Bytes langen verschlüsselten Byte-array welches auch genau fehlerfrei übertragen wird. Nur läßt es sich am Handy entschlüsseln jedoch nicht in PHP oder lokal.

Also das zu verschlüsselnde Bytearray b enthält nur 5 Bytes, ich arbeite nur mit Byte-arrays um keine Probleme Zeichenkodierung zu bekommen:
54,53,53,51,55

private Cipher cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byteBufferEncrypt = new byte[320];
cipher.doFinal(b, 0, b.length, byteBufferEncrypt);

// Debug - test ob entschlüsseln wieder geht:
// byteBufferEncrypt enthält nun 320 verschlüsselte Bytes (entspricht verschlüsselungsstärke 320*8 bits vom Schlüssel)
// diese 320 Bytes habe ich genau gleich am Handy und am PC an dieser Stelle
// String s enthält den privaten Schlüssel, hier abgekürzt
try {
String s = "MIIF3g.....";
byte [] encoded = Base64.decode(s, Base64.DEFAULT);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey debugprivateKey = (RSAPrivateKey) fact.generatePrivate(privateKeySpec);
Cipher CheckCipher = Cipher.getInstance("RSA");
CheckCipher.init(Cipher.DECRYPT_MODE, debugprivateKey );
byte[] Test = CheckCipher.doFinal(byteBufferEncrypt);
Test.toString();
// Am handy klappt es soweit, am PC schmiert er bei doFinal ab.
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException e) {
e.printStackTrace();
}


Vom Debuggen bekomme ich am ende in den Variablen "Test" wieder meine 5 Bytes vom Anfang und ich schreibe die Variable byteBufferEncrypt in eine Datei, diese ist genau 320 Bytes lang (wie auch die die Stärke der Verschlüsselung)
Ich habe die Datei auf meinen PC kopiert und kann sie auch mit dem richtigen privaten Schlüssel nicht mehr entschlüsseln...

Ich habe zuerst gedacht die Datei wird vielleicht falsch kopiert, aber aktuell sehe ich das die 320 Bytes vom genau gleich sind und auch der private Schlüssel gleich ist, der Programmcode ist komplett kopiert (die Try-anweisung) und dennoch geht es nicht.

hat irgendwer noch eine Idee?

Danke
René

3 Antworten

0 Punkte
Beantwortet von gresti Experte (1.8k Punkte)
Hallo René

schau doch mal ob Du irgendwo eine "AES-Verschlüsselung" eingestellt hast.

viel Erfolg wünscht dir

Peter
0 Punkte
Beantwortet von mixmax Experte (2.2k Punkte)
Danke schonmal für die Idee - ich habe es wie unten in eine eigene Funktion ausgelagert und einmal in der APK am handy und in einer eigenen Klasse getestet. in der APK gehts und in der Klasse nicht.

ich denke das mit der initialisierung der verschlüsselung mittels

KeyFactory fact = KeyFactory.getInstance("RSA");

sollte doch eigentlich in beiden fällen eine gleiche ver und entschlüsselung verursachen.. Gibt es dazu eine Eigenschaft die ich nicht festgelegt habe oder auf Unterschied auf beiden System prüfen kann?

Zum verschlüsseln initiiere ich den Schlüssel wie folg:

RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger("348......4227"), new BigInteger("65537"));
RSAPublicKey publicKey = (RSAPublicKey) fact.generatePublic(pubKeySpec);


zum Entschlüsseln wie hier:
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import android.util.Base64;
import java.math.BigInteger;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.BadPaddingException;
import javax.crypto.ShortBufferException;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.io.IOException;


public class test {
public static void main(String args[]) throws FileNotFoundException, FileNotFoundException,
UnsupportedEncodingException, IOException, NoSuchAlgorithmException, InvalidKeySpecException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
ShortBufferException {
//Schlüsselerstellung und Verschlüsselungsobjekt
Cipher CheckCipher = Cipher.getInstance("RSA");
KeyFactory fact = KeyFactory.getInstance("RSA");
// Größe verschlüsselter Bytebuffer entspricht verschlüsselungsstärke
// Maximale Länge unverschlüsselter Daten ist 11 Bytes kleiner (bei mehr daten Schleife bauen!)
byte[] encryptedBuffer = new byte[320];
//Öffentlicher Schlüssel
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger("3...7"), new BigInteger("6...7"));
RSAPublicKey publicKey = (RSAPublicKey) fact.generatePublic(pubKeySpec);
//Privater Schlüssel
byte[] encoded = Base64.decode("MIIF3gI...Z1B", Base64.DEFAULT);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encoded);
RSAPrivateKey debugprivateKey = (RSAPrivateKey) fact.generatePrivate(privateKeySpec);

// Selber verschlüsselte Daten mit gleichen öffentlichen Schlüssel wie am Handy
String OutPutEncryption = "debug.exponent.javatest2.txt";
CheckCipher.init(Cipher.ENCRYPT_MODE, publicKey);
DataOutputStream cryptFile = new DataOutputStream(new FileOutputStream(OutPutEncryption));
byte[] decryptedBuffer = new byte[]{100, 110, 112, 99, 64};
CheckCipher.doFinal(decryptedBuffer, 0, 5, encryptedBuffer);
cryptFile.write(encryptedBuffer);
cryptFile.close();

// Dateiname für testbytes (kopierte Datei von Handy oder selber verschlüsselt)
String SourceFile = "debug.exponent.javatest2.txt";
CheckCipher.init(Cipher.DECRYPT_MODE, debugprivateKey);
DataInputStream readCryptFileDeb = new DataInputStream(new FileInputStream(SourceFile));
readCryptFileDeb.read(encryptedBuffer); // Lese nur den ersten 320b block als test
readCryptFileDeb.close();
byte[] Test = CheckCipher.doFinal(encryptedBuffer);
System.out.println(new String(Test));
}
}


[*]Code aktuallisiert
0 Punkte
Beantwortet von mixmax Experte (2.2k Punkte)
Vielleicht hat jemand schon einen Tipp für mich - ich habe zumindest etwas rausgefunden:

am Handy wird mir als "Provider" "BC version 1.45" angezeigt, am Computer steht "SunRsaSign version 1.7"
beim erstellen und laden der Schlüssel kann man den Provider wohl angeben, da ich später das am Server in PHP entschlüsseln möchte muss ich da wohl auch schauen was verwendet wird oder die art der Schlüsselübergabe umbauen...

Cipher CheckCipher = Cipher.getInstance("RSA");
KeyFactory fact = KeyFactory.getInstance("RSA", "SunRsaSign");

man darf ihn nicht beim erstellen des Cipherobjekts angeben, da scheint Provider eine andere Bedeutung zu haben.
...