我一直在搜索这个网站以及其他网站以寻找答案,但没有找到真正的网站。
我的问题是Freedom Hack(允许用户在不付费的情况下进行应用内购买)的确切做法。也就是说,该过程的哪个部分被改变了。我找到了this list的hack适用的应用程序,其中一些条目的日期是本月,这意味着它还没有完全修复。我看到的响应是“验证服务器中的应用程序”,但是如果hack例如改变了Java.Security的签名验证功能,那么它总是返回true,那么在服务器中添加我自己的签名就不会帮助很多。
答案 0 :(得分:14)
我不知道作者是否仍然关注这个话题。但是我花了一些时间来找出(谷歌搜索)自由工作的方式以及如何防止它(直到他们更新自由工作的方式)在我的项目中并且它有效。我的实现非常简单,您无需通过向服务器发送请求进行验证(这会影响性能并且需要花费更多精力来实现它)。
当前实现的自由是它将java.security.Signature.verify(byte[])
的所有方法调用替换(重定向)到自由的jni方法,而jern方法只是总是返回true (or 1)
。
看看java.security.Signature.verify(byte[])
:
public final boolean verify(byte[] signature) throws SignatureException {
if (state != VERIFY) {
throw new SignatureException("Signature object is not initialized properly");
}
return engineVerify(signature);
}
此处engineVerify
方法是abstract protected
方法,首先在java.security.SignatureSpi
(Signature extends SignatureSpi
)中定义。
好吧,那就够了,因为我不能相信java.security.Signature.verify(byte[])
方法,我会直接使用engineVerify
方法。要做到这一点,我们需要使用反射。修改verify
的{{1}}方法:
IABUtil/Security
要:
public static boolean verify(PublicKey publicKey, String signedData, String signature) {
Signature sig;
try {
sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
if (!sig.verify(Base64.decode(signature))) {
Log.e(TAG, "Signature verification failed.");
return false;
}
return true;
} catch (...) {
...
}
return false;
}
这很简单,但它适用于当前的自由实现,直到将来更新其算法。
答案 1 :(得分:9)
然后在服务器中添加我自己的签名并不会有多大帮助。
这不正确,签名是" Freedom"使用无效,订单ID也无效。
我为确保我的应用程序安全所做的是:
将isPurchaseValid(myPurchase.getSignature(), myPurchase.getOriginalJson())
发送到我的服务器以进行验证,并且它适用于实际购买,但每次都会自由失败。
在服务器上,我检查签名是否匹配
如果匹配,我会联系" Google API Google Play Android Developer API> androidpublisher.inapppurchases.get"验证Purchase是否存在并返回我的开发人员有效负载。
然后我使用开发人员有效负载来确保此次购买是针对此特定用户而非其他用户而且此用户正在向我发送他的数据。
P.S。开发人员有效负载是您在从Android应用购买之前设置的String
,它应该是您的用户独有的。
它可能需要做很多工作,但它确保没有人会以自由和成功的方式购买你的东西。
我唯一不能做的就是不要让自由对我的申请产生影响,例如Path中的人做了一些我不知道是什么让自由变得没有任何影响! !
答案 2 :(得分:2)
我使用这样的东西,我知道与远程服务器检查您的签名相比,这不是一个好的解决方案。我正在检查是否安装了自由应用程序,如果是,我是不是要打开我的应用程序。
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
if(isHackerAppIsntalled())
finish();
}
private boolean isHackerAppInstalled() {
final PackageManager pm = getApplication().getPackageManager();
List<ApplicationInfo> packages = pm
.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
String packageName = packageInfo.packageName;
if (packageName.contains("cc.madkite.freedom")
|| packageName.contains("madkite.freedom")) {
return true;
}
}
return false;
}