当前位置: 首页 > 知识库问答 >
问题:

如何解码SafetyNet JWS响应?

麹飞航
2023-03-14
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);
                }
            }
        });
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;
    }
}
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库来解码令牌。

首先我尝试了组:“com.auth0.android”,名称:“jwtdecode”,版本:“1.1.1”

 final JWT jwt = new JWT(jwsResult);
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)
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. 
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);
        }

我在我的Android应用程序中做错了什么,阻止了auth0 Android jwt库的正常工作?

然后我在我的Android应用程序中尝试了'io.jsonwebtoken:jjwt:0.9.0'库。

当我执行这个代码时:-

Jwts.parser().parse(jwsResult).getBody();
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().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)

我从这个问题base64:java.lang.IllegalArgumentException:非法字符中发现了java.lang.IllegalArgumentException:bad base-64问题的修复程序

解码前只需替换jws令牌中的字符

token.replace('-', '+').replace('_', '/')

共有1个答案

空英达
2023-03-14

我发现这个库不仅能完成工作,而且在Android上运行良好。

// 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

 类似资料:
  • 问题内容: 我正在使用以下代码从api端点登录和检索数据,但似乎响应已编码,因此我无法读取内容。我正在使用请求requestes-0.0.1 当我在控制台上打印相同的响应 有人可以告诉我如何解码和读取响应中的数据 问题答案: 响应通过brotli压缩进行编码。标准库不支持此压缩方法。您可以从pypi安装第三方软件包以将其解压缩- 有许多可用的软件包。 例如 如果您不想避免安装第三方模块,请从请求中

  • 我正在使用下面的代码登录apiendpoint并从中检索数据,但响应似乎已编码,我无法读取内容。我正在使用request-requestes-0.0.1 当我在控制台上打印相同的响应 有人能告诉我如何解码和读取响应中的数据吗

  • 我将feign与OkHttpClient一起使用,并希望使用重试机制对返回状态代码200、ok和空正文的endpoint进行短轮询。用假动作可能吗?在状态代码2xx上没有调用自定义错误解码器。还有其他更喜欢的方式来进行短轮询吗?顺便说一句,我在用科特林。

  • 第一次尝试将SAML实现为SP。我们决定尝试在定制的MVC框架中使用SimpleSAMLphp,因为我们认为这会节省时间。 我的问题是,我最终进入了一个无限循环,或者属性是空的。 我已经在SimpleSAMLphp中配置了元数据,并从authenticate接口对其进行了测试。idP有一个回发URL集,与我们开始的位置不同,因此: 用户点击域名。com/sso我们创建了新的 如果我们这样做,我们必

  • 在我的应用程序中,我必须知道,从一个列表中有一个服务器地址,这些地址是向上的。我发现的解决方案是从Spring引导执行器调用健康endpoint,对它们每个。JSon reponse是: 在应用程序的其他部分,我使用Spring-Cloud中的Feign客户机,这些客户机使用注释定义,它工作得很好: 不幸的是,这种配置不允许重用同一个客户机来调用不同地址上的同一个endpoint。因此,我必须定义

  • 问题内容: 我对iOS应用程序开发非常陌生,并且从服务器收到以下响应: 请任何人帮助我了解如何在我的应用程序中使用员工ID和员工姓名。 问题答案: 您的JSON数据看起来像“嵌套JSON”,这意味着您必须将其反序列化两次。 第一个反序列化从您的JSON数据中提取一个字符串: 现在是字符串 再次是JSON数据。第二个反序列化提取数组: 现在您可以像访问它