Строковое шифрование RSA в Android - PullRequest
6 голосов
/ 05 марта 2011

Ситуация:

Я хочу приложение, которое шифрует строку с использованием RSA.У меня есть открытый ключ, сохраненный в res / raw, и, поскольку ключ равен 1024 битам, результирующая строка должна иметь длину 128 байт.Однако полученная строка после шифрования имеет длину 124, в результате чего происходит сбой расшифровки.

Я использую функцию для восстановления открытого ключа:

private PublicKey getPublicKey() throws Exception {
    InputStream is = getResources().openRawResource(R.raw.publickey);
    DataInputStream dis = new DataInputStream(is);
    byte [] keyBytes = new byte [(int) is.available()];
    dis.readFully(keyBytes);
    dis.close();

    X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePublic(spec);
}

И кодфункции, которую я использую для шифрования:

private String rsaEncrypt (String plain) {

    byte [] encryptedBytes;
    Cipher cipher = Cipher.getInstance("RSA");
    PublicKey publicKey = getPublicKey();
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    encryptedBytes = cipher.doFinal(plain.getBytes());
    String encrypted = new String(encryptedBytes);
    return encrypted;

}

PD: код отлично работает в настольном приложении, просто вылетает в Android.

Iдействительно буду признателен за любую помощь,

Большое спасибо.

1 Ответ

6 голосов
/ 05 марта 2011

String encrypted = new String(encryptedBytes);

- это ошибка.Выходные данные от криптопреобразований представляют собой двоичные байты.Вы не можете надежно хранить их как строки.

Использование is.available(), вероятно, также является ошибкой, но я не уверен в этом случае.

Наконец, это одна из моих любимых мозолей, когдалюди используют версии кодировки по умолчанию new String(...) и String.getBytes().Это очень редко правильная вещь, особенно в том смысле, что Java утверждает, что она «пишите один раз, запускайте везде».Набор символов по умолчанию отличается на разных платформах, что вызовет ошибку в вашем коде, даже если вы все сделаете правильно.Вы должны всегда указывать конкретную кодировку.В каждом случае, который я когда-либо видел, простое использование кодировки UTF-8 (Charset.forName("UTF-8");) всегда будет работать и эффективно представлять данные.

...