我想使用SafetyNet认证API (请记住,这个文档似乎已经过时了,因为它使用的方法已经过时了)。使用Play Services的最新版本(11.0.1),我得到了以下代码:
SecureRandom secureRandom = new SecureRandom();
byte[] nonce = new byte[16];
secureRandom.nextBytes(nonce); // just some random bytes for testing
SafetyNet.getClient(this)
.attest(nonce, API_KEY)
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
SafetyNetApi.AttestationResponse result = task.getResult();
String jws = result.getJwsResult();
Log.d(TAG, "JWS: " + jws);
} else {
Exception e = task.getException();
if (e instanceof ApiException) {
Log.e(TAG, "Attestation failure: " + ((ApiException) e).getStatusMessage() + ", code: " + ((ApiException) e).getStatusCode(), e);
} else {
Log.e(TAG, "Attestation failure: " + e, e);
}
}
});其中,API_KEY是Google控制台中的API键。这段代码在Activity的onCreate(...)中被调用。无论我尝试了什么,它都会导致失败,e是ApiException的一个实例,但它没有提供任何关于出错的有用信息,因为状态消息是null,状态代码是8,根据文献资料的说法,这是一个“内部错误”。我试图用5秒钟的延迟来调用它,但没有成功。测试设备有API 24,谷歌播放服务11.0.55。
有人知道哪里出了问题,有什么解决办法吗?
编辑:旧的SafetyNet.SafetyNetApi.attest(googleApiClient, nonce)方式似乎很好,但它被废弃了,所以我不想使用它。
发布于 2017-06-18 15:30:20
基于这个线程,如果您得到错误代码8 (INTERNAL_ERROR),请在开发控制台中检查您的应用程序注册。请注意,每个注册的Android客户端都通过(包名,Android签名证书SHA-1)对进行唯一标识。如果您的调试和生产环境有多个包名/签名证书,请确保注册它们的每一对。
核实:
如果它不起作用,我建议你联系谷歌游戏团队寻求帮助。您可以通过以下链接联系到它们:https://support.google.com/googleplay#topic=3364260&contact=1。
发布于 2017-11-15 01:29:16
确保在以下代码中使用了正确的WEB密钥:
SafetyNet.getClient(this)
.attest(nonce, WEB_API_KEY)......请参阅下面的图像以查找WEB键:FCM控制台
发布于 2019-11-06 05:41:52
// Build.gradle
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.firebase:firebase-messaging:20.1.0'
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'com.google.android.gms:play-services-safetynet:17.0.0'
implementation 'com.google.android.gms:play-services-tasks:17.0.0'
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.safetynet.SafetyNetClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.safetynet.SafetyNetClient;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNetApi.AttestationResponse;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;
@Override
public void onConnected(Bundle bundle) {
Log.d("My Project Name:", "Google play services connected");
runSafetyNetTest(mContext);
}
private byte[] getRequestNonce(String data) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byte[] bytes = new byte[24];
mRandom.nextBytes(bytes);
try {
byteStream.write(bytes);
byteStream.write(data.getBytes());
} catch (IOException e) {
return null;
}
public void runSafetyNetTest(Context context) {
String nonceData = "734K78J56KJ745JH78LKJ9CSOC3477tj35f345j7" + System.currentTimeMillis();
byte[] nonce = getRequestNonce(nonceData);
SafetyNetClient client = SafetyNet.getClient(context);
Task<SafetyNetApi.AttestationResponse> task = client.attest(nonce, this.googleDeviceVerificationApiKey);
task.addOnSuccessListener( mSuccessListener).addOnFailureListener(mFailureListener);
}
private OnSuccessListener<SafetyNetApi.AttestationResponse> mSuccessListener =
new OnSuccessListener<SafetyNetApi.AttestationResponse>() {
@Override
public void onSuccess(SafetyNetApi.AttestationResponse attestationResponse) {
mResult = attestationResponse.getJwsResult();
// writeLog( "Success! SafetyNet result:\n" + mResult + "\n");
final String jwsResult = mResult;
final SafetyNetResponse response = parseJsonWebSignature(jwsResult);
lastResponse = response;
//only need to validate the response if it says we pass
if (!response.isCtsProfileMatch() || !response.isBasicIntegrity()) {
// This is Result........
callback.success(response.isCtsProfileMatch(), response.isBasicIntegrity());
return;
} else {
//validate payload of the response
if(true/*validateSafetyNetResponsePayload(response)*/) {
if (googleDeviceVerificationApiKey != "")
{
//if the api key is set, run the AndroidDeviceVerifier
AndroidDeviceVerifier androidDeviceVerifier = new AndroidDeviceVerifier(googleDeviceVerificationApiKey, jwsResult);
androidDeviceVerifier.verify(new AndroidDeviceVerifier.AndroidDeviceVerifierCallback() {
@Override
public void error(String errorMsg) {
callback.error(RESPONSE_ERROR_VALIDATING_SIGNATURE, "Response signature validation error: " + errorMsg);
}
@Override
public void success(boolean isValidSignature) {
if (isValidSignature) {
callback.success(response.isCtsProfileMatch(), response.isBasicIntegrity());
} else {
callback.error(RESPONSE_FAILED_SIGNATURE_VALIDATION, "Response signature invalid");
}
}
});
} else {
Log.w(TAG, "No google Device Verification ApiKey defined");
callback.error(RESPONSE_FAILED_SIGNATURE_VALIDATION_NO_API_KEY, "No Google Device Verification ApiKey defined. Marking as failed. SafetyNet CtsProfileMatch: " + response.isCtsProfileMatch());
}
} else {
callback.error(RESPONSE_VALIDATION_FAILED, "Response payload validation failed");
}
}
}
};
private OnFailureListener mFailureListener = new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// An error occurred while communicating with the service.
mResult = null;
if (e instanceof ApiException) {
// An error with the Google Play Services API contains some additional details.
ApiException apiException = (ApiException) e;
writeLog( "Error: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " +
apiException.getStatusMessage());
} else {
// A different, unknown type of error occurred.
writeLog( "ERROR! " + e.getMessage());
}
}
};https://stackoverflow.com/questions/44598587
复制相似问题