Java Android - расшифрованный массив байтов длиной 255 байтов вместо «Hello World!». - PullRequest
1 голос
/ 25 октября 2011

За последние несколько недель я много читаю, чтобы реализовать алгоритм шифрования / дешифрования для моего приложения для Android. Я использую лицензионный ключ, который загружается с моего веб-сайта и хранится во внешнем хранилище моего устройства Android. приложение считывает содержимое файла и расшифровывает его с помощью открытого ключа сервера (да, я знаю, что должен использовать закрытый ключ клиента, но для моей цели это нормально). Проблема в том, что в последней строке много черного квадрата с вопросительным знаком внутри. я прочитал много других постов здесь о stackoverflow, но я думаю, что «единственная» проблема заключается в том, что, даже если в строке должно быть 10 символов, длина строки составляет 255 байтов (с 2048-битным ключом RSA) и остальные символы заполнены черным "". Почему newPlainText var не такой длинный, как "Hello World!" ? Здесь под моим кодом ... Большое спасибо заранее!

public boolean licenseValid() throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException{
    java.io.File file = new java.io.File(Environment.getExternalStorageDirectory().toString() ,
            "/folder/file.lic");
    byte[] fileBArray = new byte[(int)file.length()];
    FileInputStream fis = new FileInputStream(file);

    // Read in the bytes
    int offset = 0;
    int numRead = 0;
    while (offset < fileBArray.length
           && (numRead=fis.read(fileBArray, offset, fileBArray.length-offset)) >= 0) {
        offset += numRead;
    }

    // Ensure all the bytes have been read in
    if (offset < fileBArray.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }

    fis.close();

    // Decrypt the ciphertext using the public key
PublicKey pubKey = readKeyFromFile();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] newPlainText = cipher.doFinal(fileBArray);

    // THE FOLLOWING TOAST PRINTS MANY <?> AND THAN THE DECRYPTED MESSAGE. THE TOTAL NUMBER OF CHARACTERS IS 255, EVEN IF I CHANGE ENCRYPTED TEXT!
toast(String.valueOf(cipher.doFinal(fileBArray).length));

    if (new String(newPlainText, "utf-8").compareTo("Hello World!") == 0)
        return true;
    else
        return false;
}

PublicKey readKeyFromFile() throws IOException {
    Resources myResources = getResources();
    //public key filename "pub.lic"
    InputStream is = myResources.openRawResource(R.raw.pub);
ObjectInputStream oin =
    new ObjectInputStream(new BufferedInputStream(is));

try {
        BigInteger m = (BigInteger) oin.readObject();
        BigInteger e = (BigInteger) oin.readObject();
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
    KeyFactory fact = KeyFactory.getInstance("RSA");
    PublicKey pubKey = fact.generatePublic(keySpec);
    return pubKey;
  } catch (Exception e) {
    throw new RuntimeException("Spurious serialisation error", e);
  } finally {
    oin.close();
   }
}

1 Ответ

2 голосов
/ 25 октября 2011

Если вы шифруете с помощью RSA, вход и выход всегда имеют ту же длину, что и ключ.В вашем случае это должно быть 256 байтов (= 2048 бит), поэтому сначала проверьте ваш код, вы пропустите байт.Когда ввод короче, вам нужно применить отступы, и похоже, что ваш сервер и клиент используют разные.Cipher.getInstance("RSA") будет использовать платформу по умолчанию, которая, вероятно, отличается для Android и Java SE.Вам нужно явно указать отступ в обеих программах, чтобы это работало.Примерно так:

Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");

Кстати, вы действительно не хотите распространять закрытый ключ с вашим приложением, поэтому использование открытого ключа является правильнымвещь которую нужно сделать.(Является ли ваша схема шифрования безопасной, это другой вопрос).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...