2016-09-02 4 views
1

Ich verwende SafetyNet API zum Prüfen, ob Gerät verwurzelt ist oder nicht und mit Hilfe des unten hilfreich Code aber dies verwendet Android Überprüfung API zur Validierung der JWT validieren Unterschrift:Wie Safety Net JWS Signatur von Kopfdaten in Android App

https://github.com/scottyab/safetynethelper

und ich mag nur auf Client-Seite validieren den Aufwand eines anderen Web-Service auf pro Tag nur 10k Anfrage aller und außerdem hat es Beschränkung zu reduzieren.

So nach dem JWS Decodierung Ich bin die unter info

Probe JWS Nachrichtenantwort

xxxx.yyy.zzzz

Kopfdaten

{"alg":"RS256","x5c":["<certificate1 string>","<certificate2 string>"]} 

Nutzdaten

bekommen
{"nonce":"<nounce>", 
"timestampMs":1472794339527, 
"apkPackageName":"<apkPackageName>", 
"apkDigestSha256":"<sha digest string>", 
"ctsProfileMatch":true, 
"extension":"<extension string>", 
"apkCertificateDigestSha256":["<apkCertificateDigestSha256 string>"],"basicIntegrity":true} 
wenn ausführen Base64-Decodierung 91.363.210

Signature in diesem Teil wird es so unten unleserlich ist die Signatur-String als

Gw09rv1aBbtd4Er7F5ww_3TT1mPRD5YouMkPkwnRXJq8XW_cxlO4428DHTJdD8Tbep-Iv3nrVRWt2t4pH1uSr2kJ9budQJuXqzOUhN93r2Hfk-UAKUYQYhp89_wOWjSCG4ySVHD4jc9S1HrZlngaUosocOmhN4SzLZN5o8BXyBdXkjhWwgArd4bcLhCWJzmxz5iZfkhDiAyeNRq09CeqjRx_plqAy8eR_OaI_2idZBNIGfd2KmLK_CKaeVjDxuC4BzJsIlVRiuLrvP362Wwhz4r1bHh8flmHr88nK99apP2jkQD2l7lPv8y5F3FN3DKhJ15CzHR6ZbiTOw1fUteifg 

Jetzt per google

„Überprüfen Sie die Kompatibilitätsprüfung Antwort in JWS letzte Element erhalten: Extrahieren Sie das SSL-Zertifikat chain aus der JWS-Nachricht. Überprüfen Sie die SSL-Zertifikatkette, und verwenden Sie den SSL-Hostnamen , um sicherzustellen, dass das Blattzertifikat an den Hostnamen attest.android.com ausgestellt wurde. Verwenden Sie das Zertifikat die Signatur der JWS Nachricht zu überprüfen.“

ich das CERT-String und Unterschrift haben, wie soll ich über die Validierung von SSL-Zertifikat gehen die Zeichenfolge und Host name matching auf den zweiten cert und , wie man Validierung Unterschrift

I Zeiger auf diese und Code benötigen würde sehr nützlich sein snipped

+0

Java Web Start hat * nichts * mit Android zu tun. Versuchen Sie, * die * hilfreichen Tag-Pop-ups * zu lesen, bevor Sie sie auf Ihren Post setzen. –

+0

@AndrewThompson Meine schlechte – user1068968

+0

Nur überprüfen, aber wenn ich die "JW * S *" Zeichenfolge an meinen Server senden, sollte ich [php-jws] (https://github.com/gamegos/php-jws) oder verwenden [php-jwt] (https://github.com/gamegos/php-jwt)? – Penn

Antwort

-1

Es gibt ein Open-Source-android-Bibliothek, die helfen führen die Validierung der Lage ist:.. jwtk/jjwt

+0

Sie haben die Frage nicht gelesen - es muss überprüft werden, ob die Signatur von Google angekommen ist. –

2

Die Art und Weise, wie Sie die JWT-Signatur auf dem Gerät validieren möchten, ist nicht sicher. Denken Sie über folgenden Fall:

  • das Gerät verwurzelt ist, Malware-Anwendung mit Root-Rechten fängt Ihre Anfrage an die Google-SafetyNet und gibt selbstsignierten Antwort.

  • Wenn Sie die Antwort mit Ihrem eigenen Server-Dienst überprüfen, erhalten Sie, dass die Antwort, die Sie erhalten, nicht von Google bereitgestellt wurde. Wenn Sie dies lokal auf dem Gerät tun, könnte dieselbe Malware-App Ihre Anfrage zur Überprüfung der JWT-Signatur abfangen und mit true antworten.

Wie auch immer, können Sie dies vor Ort tun:

  1. Sie müssen API-Schlüssel von Google-Entwickler für Ihre Anwendung zu erhalten.
  2. Verwenden Sie das Android Geräte-Verification-API: Von Android-Entwickler:

Um den Android Geräte-Verification-API zu verwenden:

eine JSON-Nachricht erstellen, den gesamten Inhalt der JWS Nachricht in dem umschließende folgendes Format:

{ "signedAttestation": "<output of> getJwsResult()>" } 

eine HTTP-POST-Anfrage Verwenden Sie die Nachricht mit einemsendenContent-Type von "application/json" auf die folgende URL: https://www.googleapis.com/androidcheck/v1/attestations/verify?key=<your API key>

Der Dienst überprüft die Integrität der Nachricht, und wenn die Nachricht gültig ist, es gibt eine JSON-Nachricht mit dem folgenden Inhalt: { “isValidSignature”: true }

Also eigentlich (Code von SafetyNet Helper):

/** 
* 
* Validates the result with Android Device Verification API. 
* 
* Note: This only validates that the provided JWS (JSON Web Signature) message was received from the actual SafetyNet service. 
* It does *not* verify that the payload data matches your original compatibility check request. 
* POST to https://www.googleapis.com/androidcheck/v1/attestations/verify?key=<your API key> 
* 
* More info see {link https://developer.android.com/google/play/safetynet/start.html#verify-compat-check} 
* 
* Created by scottab on 27/05/2015. 
*/ 
public class AndroidDeviceVerifier { 

    private static final String TAG = AndroidDeviceVerifier.class.getSimpleName(); 

    //used to verifiy the safety net response - 10,000 requests/day free 
    private static final String GOOGLE_VERIFICATION_URL = "https://www.googleapis.com/androidcheck/v1/attestations/verify?key="; 

    private final String apiKey; 
    private final String signatureToVerify; 
    private AndroidDeviceVerifierCallback callback; 

    public interface AndroidDeviceVerifierCallback{ 
     void error(String s); 
     void success(boolean isValidSignature); 
    } 

    public AndroidDeviceVerifier(@NonNull String apiKey, @NonNull String signatureToVerify) { 
     this.apiKey = apiKey; 
     this.signatureToVerify = signatureToVerify; 
    } 

    public void verify(AndroidDeviceVerifierCallback androidDeviceVerifierCallback){ 
     callback = androidDeviceVerifierCallback; 
     AndroidDeviceVerifierTask task = new AndroidDeviceVerifierTask(); 
     task.execute(); 
    } 

    /** 
    * Provide the trust managers for the URL connection. By Default this uses the system defaults plus the GoogleApisTrustManager (SSL pinning) 
    * @return array of TrustManager including system defaults plus the GoogleApisTrustManager (SSL pinning) 
    * @throws KeyStoreException 
    * @throws NoSuchAlgorithmException 
    */ 
    protected TrustManager[] getTrustManagers() throws KeyStoreException, NoSuchAlgorithmException { 
     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     //init with the default system trustmanagers 
     trustManagerFactory.init((KeyStore)null); 
     TrustManager[] defaultTrustManagers = trustManagerFactory.getTrustManagers(); 
     TrustManager[] trustManagers = Arrays.copyOf(defaultTrustManagers, defaultTrustManagers.length + 1); 
     //add our Google APIs pinning TrustManager for extra security 
     trustManagers[defaultTrustManagers.length] = new GoogleApisTrustManager(); 
     return trustManagers; 
    } 



    private class AndroidDeviceVerifierTask extends AsyncTask<Void, Void, Boolean>{ 

     private Exception error; 

     @Override 
     protected Boolean doInBackground(Void... params) { 

      //Log.d(TAG, "signatureToVerify:" + signatureToVerify); 

      try { 
       URL verifyApiUrl = new URL(GOOGLE_VERIFICATION_URL + apiKey); 

       SSLContext sslContext = SSLContext.getInstance("TLS"); 
       sslContext.init(null, getTrustManagers(), null); 

       HttpsURLConnection urlConnection = (HttpsURLConnection) verifyApiUrl.openConnection(); 
       urlConnection.setSSLSocketFactory(sslContext.getSocketFactory()); 

       urlConnection.setRequestMethod("POST"); 
       urlConnection.setRequestProperty("Content-Type", "application/json"); 

       //build post body { "signedAttestation": "<output of getJwsResult()>" } 
       String requestJsonBody = "{ \"signedAttestation\": \""+signatureToVerify+"\"}"; 
       byte[] outputInBytes = requestJsonBody.getBytes("UTF-8"); 
       OutputStream os = urlConnection.getOutputStream(); 
       os.write(outputInBytes); 
       os.close(); 

       urlConnection.connect(); 

       //resp ={ “isValidSignature”: true } 
       InputStream is = urlConnection.getInputStream(); 
       StringBuilder sb = new StringBuilder(); 
       BufferedReader rd = new BufferedReader(new InputStreamReader(is)); 
       String line; 
       while ((line = rd.readLine()) != null) { 
        sb.append(line); 
       } 
       String response = sb.toString(); 
       JSONObject responseRoot = new JSONObject(response); 
       if(responseRoot.has("isValidSignature")){ 
        return responseRoot.getBoolean("isValidSignature"); 
       } 
      }catch (Exception e){ 
       //something went wrong requesting validation of the JWS Message 
       error = e; 
       Log.e(TAG, "problem validating JWS Message :" + e.getMessage(), e); 
       return false; 
      } 
      return false; 
     } 

     @Override 
     protected void onPostExecute(Boolean aBoolean) { 
      if(error!=null){ 
       callback.error(error.getMessage()); 
      }else { 
       callback.success(aBoolean); 
      } 
     } 
    } 

} 
Verwandte Themen