Android billing-в безопасности файлов.java должен ли base64EncodedPublicKey быть закодированным значением?

должен ли я вставить фактический открытый ключ моего приложения прямо в значение этой переменной?

или я должен кодировать его, а затем, независимо от закодированной строки, Я бы сделал эту строку в значение этой переменной?

Что это должно быть?

4 ответов


открытый ключ присутствует в консоли разработчика Android (который можно найти в разделе "Редактировать профиль")уже кодируется Base64. Просто скопируйте и вставьте содержимое ключа в исходный файл. Например, если у вас есть что-то вроде этого:

enter image description here

затем в Security.java:

String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQ......";

как говорится в примере кода Google для выставления счетов в приложении, вы должны запутать этот открытый ключ.

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

Я использую очень простой код Java для создания класса Java, который вернет мне открытый ключ. Основная идея заключается в использовании рекурсии для воссоздания ключа с использованием внутреннего статического класса. это просто пища для размышлений.

это" достаточно хороший " подход для моего нишевого рынка. См.этот секретный вопрос stackexchange для получения дополнительной информации о обфускации.

public static void main(String[] args) throws Exception {
    String className = genClassName();
    PrintWriter writer = new PrintWriter("C:\" + className + ".java", "iso-8859-1");
    printClass(className, writer, "XXXXXX-YOUR-PUBLIC-KEY-GOES-HERE-XXXXXXX", true);
    writer.close();
}

private static String genClassName() {
    return "Class" + UUID.randomUUID().toString().replaceAll("-", "");
}

private static String printClass(String thisClass, PrintWriter writer, String key, boolean root) {
    int split = key.length() / 2;
    if (split < 10) {
        writer.println("public " + (root ? "" : "static") + " class " + thisClass + " {");
        writer.println("public static String get() {");
        writer.println("return \"" + key + "\";");
        writer.println("}");
        writer.println("}");
    } else {
        String first = key.substring(0, split);
        String last = key.substring(split, key.length());
        writer.println("public " + (root ? "" : "static") + " class " + thisClass + " {");
        String class1 = printClass(genClassName(), writer, first, false);
        String class2 = printClass(genClassName(), writer, last, false);
        writer.println("public static String get() {");
        writer.println("return " + class1 + ".get() + " + class2 + ".get();");
        writer.println("}");
        writer.println("}");
    }

    return thisClass;
}

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

вы не можете полностью скрыть ключ от посторонних глаз, но вы можете скрыть. Вы можете разбить строку Base64 на несколько строковых констант в разных местах и объединить их перед использованием. Лучше дать кускам незаметные имена (не как MY_PUBLIC_KEY_PART_4). Вы также можете применить к нему дополнительный уровень мягкого шифрования - что-то вроде XOR a value. Вы можете добавить проверку целостности - убедитесь, что ключ не был подменен (скажем, хранить хэш-ключа в другом месте и проверить). Но это все еще безопасность через неизвестность - достаточно решительный хакер пройдет.

также рассмотрим ProGuard, встроенный инструмент обфускации кода.


Если у вас есть серверный компонент как часть вашего приложения, то вы можете поместить элементы безопасности, в том числе ваш открытый ключ на сервер. На сервере вы можете сгенерировать nonce и проверить покупку (я переместил свой в Службу RESTFul WCF). Если ваш серверный компонент основан на .NET, вам, вероятно, придется создать модуль и показатель из вашего открытого ключа, чтобы вы могли использовать RNGCryptoServiceProvider класса. Есть видео ввода-вывода Google, которое дает обзор в В Приложении Биллинг среди других.