Ответ 1
Я не знаю, продолжает ли автор следовать этой теме или нет. Но я провел некоторое время, чтобы узнать (googling), как работает свобода и как ее предотвращать (пока они не обновляют способ свободы) в моем проекте, и это работает. Моя реализация очень проста, и вам не нужно проверять, отправив запрос на сервер (что влияет на производительность и прикладывает больше усилий для ее реализации).
Текущая реализация свободы заключается в том, что она заменит (перенаправляет) все вызовы метода java.security.Signature.verify(byte[])
на метод свободы jni, который в свою очередь просто просто возвращает 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
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;
}
To:
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());
Method verify = java.security.SignatureSpi.class.getDeclaredMethod("engineVerify", byte[].class);
verify.setAccessible(true);
Object returnValue = verify.invoke(sig, Base64.decode(signature));
if (!(Boolean)returnValue) {
Log.e(TAG, "Signature verification failed.");
return false;
}
return true;
} catch (...) {
...
}
return false;
}
Это просто, но он работает с текущей реализацией свободы, пока не обновит свой алгоритм в будущем.