2017-12-07 24 views
0

Android Application内でGoogleが提供するSafetyNetについて調査中です。SafetyNet JWSレスポンスのデコード方法は?

まずはSafetyNet attest APIを呼び出し、Base64はGoogle提供の例に示すように部品をデコードしました。

SafetyNet.getClient(this).attest(NONCE, <API KEY>) 
     .addOnSuccessListener(this, new OnSuccessListener<SafetyNetApi.AttestationResponse>() { 
      @Override 
      public void onSuccess(final SafetyNetApi.AttestationResponse attestationResponse) { 
       initialDataExtraction(attestationResponse.getJwsResult()); 
      } 
     }) 
     .addOnFailureListener(this, new OnFailureListener() { 
      @Override 
      public void onFailure(@NonNull final Exception exception) { 
       if (exception instanceof ApiException) { 
        final ApiException apiException = (ApiException) exception; 
        Log.e(TAG, "onFailure: " + apiException.getMessage() + " " + apiException.getStatusCode()); 
       } else { 
        Log.e(TAG, "Error: ", exception); 
       } 
      } 
     }); 

次のように私は、JWSの部分を抽出: -

private byte[] initialDataExtraction(final String jwsResult) { 

    final String[] jwsResultParts = jwsResult.split("[.]"); 
    if (jwsResultParts.length == 3) { 
     final byte[] header = Base64.decode(jwsResultParts[0], Base64.NO_WRAP); 
     final byte[] data = Base64.decode(jwsResultParts[1], Base64.NO_WRAP); 
     final byte[] signature = Base64.decode(jwsResultParts[2], Base64.NO_WRAP); 

     Log.d(TAG, "initialDataExtraction: header = " + new String(header, UTF_8)); 
     Log.d(TAG, "initialDataExtraction: data = " + new String(data, UTF_8)); 
     Log.d(TAG, "initialDataExtraction: signature = " + new String(signature, UTF_8)); 

     return data; 
    } else { 
     Log.e(TAG, "initialDataExtraction: Failure: Illegal JWS signature format. The JWS consists of " + jwsResultParts.length + " parts instead of 3."); 
     return null; 
    } 
} 

私は部品やデコードがOK完了時間の大部分をデコードするandroid.util.Base64を使用しています。

は時折私もこの例外を受け取る: -
java.lang.IllegalArgumentException: bad base-64 
at android.util.Base64.decode(Base64.java:161) 
at android.util.Base64.decode(Base64.java:136) 
at android.util.Base64.decode(Base64.java:118) 

署名の一部をデコードします。

この断続的なエラーを表示するためにデコードするとき、私は間違って何をしていますか?

次に、JWTライブラリを使用してトークンをデコードしました。

は、最初に私は私が試したコードは一貫この例外はAuth0ライブラリができないことに起因すると思わ

com.auth0.android.jwt.DecodeException: The token's payload had an invalid JSON format. 
at com.auth0.android.jwt.JWT.parseJson(JWT.java:235) 
at com.auth0.android.jwt.JWT.decode(JWT.java:203) 
at com.auth0.android.jwt.JWT.<init>(JWT.java:40) 
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 23 path $. 
at com.google.gson.Gson.fromJson(Gson.java:899) 
at com.google.gson.Gson.fromJson(Gson.java:852) 
at com.google.gson.Gson.fromJson(Gson.java:801) 

次のエラーで失敗し

final JWT jwt = new JWT(jwsResult); 

あるgroup: 'com.auth0.android', name: 'jwtdecode', version: '1.1.1'

を試してみましたJWS Specは値がJSONアレイで表されていることを明確に示しているので、ヘッダ4.1.6. "x5c" (X.509 Certificate Chain) Headerの形式は奇妙です。-

The "x5c" (X.509 Certificate Chain) Header Parameter contains the 
    X.509 public key certificate or certificate chain [RFC5280] 
    corresponding to the key used to digitally sign the JWS. The 
    certificate or certificate chain is represented as a JSON array of 
    certificate value strings. 

私はコピーして、同じJWSを貼り付ける場合は、純粋なJavaプロジェクトに文字列を招き、compile 'com.auth0:java-jwt:3.3.0'を使用してこのコードを使用: -

String token = "<JWS TOKEN>"; 
     try { 
      final DecodedJWT jwt = JWT.decode(token); 
      System.out.println("Header = " + jwt.getHeader()); 
      System.out.println("Payload = " + jwt.getPayload()); 
      System.out.println("Signature = " + jwt.getSignature()); 
       } catch (JWTDecodeException exception){ 
      throw new RuntimeException(exception); 
     } 

JWSトークンが正常に復号されます。

私のAndroidアプリケーションで、auth0 android jwtライブラリが必要に応じて動作しなくなるのは何ですか?

その後、Androidアプリケーション内で'io.jsonwebtoken:jjwt:0.9.0'ライブラリを試しました。

私はJwtsに渡す必要がありますかどのような署名キー
java.lang.IllegalArgumentException: A signing key must be specified if the specified JWT is digitally signed. 
at io.jsonwebtoken.lang.Assert.notNull(Assert.java:85) 
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:331) 

- :それはで失敗

Jwts.parser().parse(jwsResult).getBody(); 

- :私はこのコードを実行

?私が持っている唯一のキーは、Google API Consoleで保持されているAPIキーです。これは私が採用すべきキーですか?

次のように私はそれを渡す:

Jwts.parser().setSigningKey<API KEY>.parse(jwsResult).getBody(); 

これはで失敗します -

java.lang.IllegalArgumentException: Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance. 
at io.jsonwebtoken.lang.Assert.isTrue(Assert.java:38) 
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:324) 

は、JWS結果をデコードし、消費するための正しいアプローチは、APIの呼び出し証明SAFETYNETから何を受けていますか?

は私が Base64: java.lang.IllegalArgumentException: Illegal character

単に、私はそれはそれは罰金で働く仕事をするだけでなく、このライブラリを識別

​​

答えて

0

をデコードする前に、JWSがトークン内の文字を置換し、この質問からjava.lang.IllegalArgumentException: bad base-64問題の修正プログラムを発見しましたアンドロイド。

// https://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt 
implementation group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '5.1' 


    try { 
     final JWSObject jwsObject = JWSObject.parse(jwsResult); 
     System.out.println("header = " + jwsObject.getHeader()); 
     System.out.println("header = " + jwsObject.getHeader().getX509CertChain()); 
     System.out.println("payload = " + jwsObject.getPayload().toJSONObject()); 
     System.out.println("signature = " + jwsObject.getSignature()); 
     System.out.println("signature = " + jwsObject.getSignature().decodeToString()); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 

いくつかの素晴らしい例が提供されています -

https://connect2id.com/products/nimbus-jose-jwt/examples

関連する問題