Android计费-在Security.java文件中,base64EncodedPublicKey应该是编码值吗?

Android计费-在Security.java文件中,base64EncodedPublicKey应该是编码值吗?,android,android-billing,Android,Android Billing,我应该将应用程序的实际公钥粘贴到此变量的值中吗 或者我应该对它进行编码,然后不管编码的字符串是什么,我都会将该字符串转换成这个变量的值 应该是哪一个?Android开发者控制台中的公钥(可以在“编辑配置文件”下找到)已经是Base64编码的。只需将密钥的内容复制粘贴到源文件中。例如,如果您有如下内容: 然后在Security.java中: String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQ......"; 您需要程序源代码中的公钥,

我应该将应用程序的实际公钥粘贴到此变量的值中吗

或者我应该对它进行编码,然后不管编码的字符串是什么,我都会将该字符串转换成这个变量的值


应该是哪一个?

Android开发者控制台中的公钥(可以在“编辑配置文件”下找到)已经是Base64编码的。只需将密钥的内容复制粘贴到源文件中。例如,如果您有如下内容:

然后在
Security.java中:

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

您需要程序源代码中的公钥,以便检查签名。是的,有一个非零的,不可避免的风险,一个破解者会发现它,用一个假货代替它,并为你的程序提供假货

您无法完全隐藏钥匙以防窥探,但您可以混淆。您可以在不同的位置将Base64字符串拆分为多个字符串常量,并在使用前将它们连接起来。最好给块起个不显眼的名字(不像
MY\u PUBLIC\u KEY\u PART\u 4
)。您还可以对其应用额外的软加密层,比如XOR值。您可以添加完整性检查-确保密钥未被伪造(例如,将密钥的哈希存储在其他位置并进行检查)。但这一切仍然是通过默默无闻的安全-一个足够坚定的黑客将通过


还考虑PROGART,内置代码混淆工具。

如果你有一个服务器组件作为应用程序的一部分,那么你可以把你的安全性的大部分元素,包括你的公钥,移到你的服务器上。在服务器上,您可以生成nonce并验证购买(我已经将我的移动到restfulwcf服务)。如果您的服务器组件是基于.NET的,那么您可能必须从公钥生成模数和指数,以便可以使用

RNGCryptoServiceProvider
类。有一个谷歌I/O视频,其中包括一个概述。

正如谷歌应用内计费示例代码所说,你应该混淆这个公钥

而不仅仅是将整个文本字符串存储在 编程,在运行时从片段或 使用位操作(例如,与其他字符串的异或)隐藏 实际密钥。密钥本身不是秘密信息,但我们不是 想让攻击者更容易用公钥替换公钥吗 然后伪造来自服务器的消息

我使用非常简单的Java代码生成Java类,该类将返回公钥。基本思想是使用递归来使用内部静态类重新创建密钥这只是思想的食粮

对于我的利基市场来说,这是一种“足够好”的方法。有关模糊处理的更多信息,请参阅

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;
}
publicstaticvoidmain(字符串[]args)引发异常{
字符串className=genClassName();
PrintWriter=新的PrintWriter(“C:\\”+类名+”.java、“iso-8859-1”);
printClass(类名,编写器,“XXXXXX-YOUR-PUBLIC-KEY-GOES-HERE-XXXXXXX”,true);
writer.close();
}
私有静态字符串genClassName(){
返回“Class”+UUID.randomUUID().toString().replaceAll(“-”,”);
}
私有静态字符串printClass(字符串thisClass、PrintWriter writer、字符串键、布尔根){
int split=key.length()/2;
如果(拆分<10){
println(“public”+(root?”:“static”)+“class”+这个类+“{”);
println(“公共静态字符串get(){”);
println(“return\”“+key+”\“;”);
writer.println(“}”);
writer.println(“}”);
}否则{
第一个字符串=键。子字符串(0,拆分);
字符串last=key.substring(拆分,key.length());
println(“public”+(root?”:“static”)+“class”+这个类+“{”);
String class1=printClass(genClassName(),writer,first,false);
String class2=printClass(genClassName(),writer,last,false);
println(“公共静态字符串get(){”);
println(“return”+class1+”.get()+“+class2+”.get();”;
writer.println(“}”);
writer.println(“}”);
}
返回这个类;
}

不需要隐藏或混淆公钥。谷歌将使用一个秘密密钥(您(开发人员)没有,也不会出现在您的应用程序中)对请求进行签名。公钥仅用于验证该签名。破解者不能使用公钥创建虚假购买。破解者可以用自己的公钥替换应用程序内存中的公钥,并用自己的私钥签署购买。这就是为什么谷歌建议你进行模糊处理。你是对的,我以为你说的是密钥本身。你的应用程序有服务器组件吗?@JohnJSmith Hi John,是的,它有:)base64EncodedPublicKey应该是你应用程序的公钥(从谷歌Play开发者控制台获得)。这不是您的开发人员公钥,而是特定于应用程序的公钥。不只是将整个文本字符串存储在程序中,而是在运行时从片段构造键,或者使用位操作(例如,与其他字符串的异或)隐藏实际键。密钥本身不是秘密信息,但我们不想让攻击者轻易地用自己的密钥替换公钥,然后从服务器上伪造消息。这是在过去,我们有一个唯一的开发人员密钥,用于许可和应用内。用于许可和应用内计费的Base64编码RSA公钥已移动,现在可以在Goggle Play中找到,方法是选择应用程序,然后单击“服务和API”选项卡。谷歌特别建议:~“与其只存储程序中嵌入的整个文本字符串,不如在运行时从片段构造键,或者使用位操作”模数和指数是什么意思?是吗