android - SafetyNet 无法获得结果

标签 android safetynet

我正在尝试通过 stackover 中一位成员的引用来学习如何实现安全网。 SafetyNet: package name always return null

第一段代码是SafetyNetVerifier的完整代码

package com.example.stack;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Base64;
import android.util.Log;

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 java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;


public class SafetyNetVerifier implements GoogleApiClient.OnConnectionFailedListener {

    private final Random mRandom = new SecureRandom();
    private String mResult;
    private GoogleApiClient mGoogleApiClient;

    private FragmentActivity activity;

    public SafetyNetVerifier(FragmentActivity activity) {
        this.activity = activity;
        buildGoogleApiClient();
        sendSafetyNetRequest();
    }

    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;
        }

        return byteStream.toByteArray();
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(activity)
                .addApi(SafetyNet.API)
                .enableAutoManage(activity, this)
                .build();
    }

    private void sendSafetyNetRequest() {
        Log.e("hqthao", "Sending SafetyNet API request.");

        String nonceData = "Safety Net Sample: " + System.currentTimeMillis();
        byte[] nonce = getRequestNonce(nonceData);

        SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)
                .setResultCallback(new ResultCallback<SafetyNetApi.AttestationResult>() {

                    @Override
                    public void onResult(SafetyNetApi.AttestationResult result) {
                        Status status = result.getStatus();
                        if (status.isSuccess()) {
                            mResult = result.getJwsResult();
                            Log.e("hqthao", "Success! SafetyNet result:\n" + mResult + "\n");
                            SafetyNetResponse response = parseJsonWebSignature(mResult);
                            Log.e("hqthao", response.toString());
                        }
                    }
                });
    }

    @Nullable
    private SafetyNetResponse parseJsonWebSignature(String jwsResult) {
        if (jwsResult == null) {
            return null;
        }
        //the JWT (JSON WEB TOKEN) is just a 3 base64 encoded parts concatenated by a . character
        final String[] jwtParts = jwsResult.split("\\.");

        if (jwtParts.length == 3) {
            //we're only really interested in the body/payload
            String decodedPayload = new String(Base64.decode(jwtParts[1], Base64.DEFAULT));

            return SafetyNetResponse.parse(decodedPayload);
        } else {
            return null;
        }
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.e("hqthao", "Error connecting to Google Play Services." + connectionResult.getErrorMessage());
    }

}

当我尝试调试时,它总是停在

SafetyNet.SafetyNetApi.attest(mGoogleApiClient,随机数)

我可以知道为什么会这样吗?我查看了 google 提供的 Safetynet 示例,他们通常会将 API key 与随机数配对。如何将 mGoogleApiClient 更改为 API KEY?

private void sendSafetyNetRequest() {
        Log.e("hqthao", "Sending SafetyNet API request.");

        String nonceData = "Safety Net Sample: " + System.currentTimeMillis();
        byte[] nonce = getRequestNonce(nonceData);

        SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)
                .setResultCallback(new ResultCallback<SafetyNetApi.AttestationResult>() {

                    @Override
                    public void onResult(SafetyNetApi.AttestationResult result) {
                        Status status = result.getStatus();
                        if (status.isSuccess()) {
                            mResult = result.getJwsResult();
                            Log.e("hqthao", "Success! SafetyNet result:\n" + mResult + "\n");
                            SafetyNetResponse response = parseJsonWebSignature(mResult);
                            Log.e("hqthao", response.toString());
                        }
                    }
                });
    }

最佳答案

您应该使用SafetyNetClient接口(interface)进行测试。示例代码如下:

SafetyNetClient client = SafetyNet.getClient(getActivity());
Task<SafetyNetApi.AttestationResponse> task = client.attest(nonce, BuildConfig.API_KEY);

您可以引用GitHub上的最新代码: https://github.com/googlesamples/android-play-safetynet/blob/master/client/java/SafetyNetSample/Application/src/main/java/com/example/android/safetynetsample/SafetyNetSampleFragment.java

关于android - SafetyNet 无法获得结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52849026/

相关文章:

java - Android - 还有一些与内存相关的问题

java - Java代码混淆的Maven插件

android - 客户使用 GCM 是否需要 Google Play 商店并拥有 Google 帐户?

android - 收到错误 : 'shared_ptr' in namespace 'std' does not name a type

Android App Bluetooth 确定配对设备之间的距离

Android 和 SafetyNet 以确保对 API 的调用仅来 self 的应用程序

android - 为什么 SafetyNet Attestation 停止工作?

android - 使用 Firebase 应用检查不起作用(调试)

node.js - 可靠地验证 JWS 证书链和域

Android:SafetyNet Attest 设备验证响应网络错误