2

我正在尝试学习如何在 stackover 中参考其他成员的参考来实施安全网。SafetyNet:包名总是返回 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, nonce)

我可以知道为什么会这样吗?我查看了 google 提供的 Safetynet 示例,他们通常会将 API 密钥与 nonce 配对。如何将 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());
                        }
                    }
                });
    }
4

2 回答 2

3

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

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/安全网样本/SafetyNetSampleFragment.java

于 2020-06-04T06:27:31.400 回答
1

据我了解,您将需要一个 SafetyNetClient 实例来执行 attest 方法,而不是 SafetyNetApi.attest,后者已被弃用且现已禁用

为了获得客户端,请使用:

SafetyNet.getClient(this).attest()

有关更多详细信息,请参见此处和此处的示例

于 2018-10-21T14:25:01.130 回答