3

我想使用SafetyNet Attestation 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_KEYGoogle Developer Console 中的 API 密钥在哪里。Activity此代码在's中调用onCreate(...)。无论我尝试什么,它都会导致失败,并且e是 的一个实例ApiException,但它没有提供任何有用的信息来说明发生了什么问题,因为状态消息是null并且状态代码是 8,根据文档,它是“内部错误”。我试图以 5 秒的延迟调用它,但没有成功。测试设备具有 API 24 和 Google Play 服务 11.0.55。

任何人都知道出了什么问题以及解决方案是什么?


编辑:旧SafetyNet.SafetyNetApi.attest(googleApiClient, nonce)方法似乎工作正常,但它已被弃用,所以我不想使用它。

4

3 回答 3

0

确保您在以下代码中使用了正确的 WEB API KEY:

SafetyNet.getClient(this)
    .attest(nonce, WEB_API_KEY)......

请参阅下图以查找 WEB API KEY: FCM 控制台

于 2017-11-15T01:29:16.413 回答
0

基于此线程,如果您收到错误代码 8 ( INTERNAL_ERROR),请在开发控制台中仔细检查您的应用注册。请注意,每个注册的 Android 客户端都由(包名称,Android 签名证书 SHA-1)对唯一标识。如果您的调试和生产环境有多个包名称/签名证书,请确保注册每一对。

验证:

  1. 打开凭据页面并选择您的项目
  2. 确保每对都有一个Android类型的 OAuth 2.0 客户端 ID。要为您的 Android 客户端创建新的 OAuth 2.0 客户端 ID,请从下拉列表中选择New Credentials->OAuth2 Client ID,选择 Android 并在此处输入您的包名称/签名证书指纹。

如果它不起作用,我建议您联系 Google Play 团队寻求帮助。您可以通过以下链接与他们联系:https: //support.google.com/googleplay#topic=3364260&contact=1

于 2017-06-18T15:30:20.377 回答
0
// 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());
           }

       }
   };
于 2019-11-06T05:41:52.323 回答