2

このようなJJWTライブラリを使用してトークンを生成しています-

    final String issuer = "my-app-auth-server@my-app-797ab.iam.gserviceaccount.com";
    final String sub = "my-app-auth-server@my-app-797ab.iam.gserviceaccount.com";
    final String aud = "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit";
    final String secret = "my-secret-key"   //only demo key , not real secret key that i am using



    final long iat = System.currentTimeMillis() / 1000L; // issued at claim
    final long exp = iat + 60L; // expires claim. In this case the token expires in 60 seconds

    final String jwtString = Jwts.builder()
                .claim("alg","HS256")
                .claim("iss", issuer)
                .claim("aud",aud)
                .claim("iat", iat)
                .claim("exp", exp)
                .claim("uid",number)
                .setSubject(sub)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();

ここに記載されているように、私が使用している秘密鍵(「my-secret-key」)は Firebase によって生成されます

しかし、上記のように生成されたトークンを使用して Firebase にサインインすると、このエラーが発生します -

com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The custom token format is incorrect. Please check the documentation.
                                                                         at com.google.android.gms.internal.zzafd.zzes(Unknown Source)
                                                                         at com.google.android.gms.internal.zzafa$zzg.zza(Unknown Source)
                                                                         at com.google.android.gms.internal.zzafl.zzet(Unknown Source)
                                                                         at com.google.android.gms.internal.zzafl$zza.onFailure(Unknown Source)
                                                                         at com.google.android.gms.internal.zzafg$zza.onTransact(Unknown Source)
                                                                         at android.os.Binder.execTransact(Binder.java:367)
                                                                         at dalvik.system.NativeStart.run(Native Method)

これは、デコードされた様子です -

ここに画像の説明を入力

助けてください、よろしくお願いします。

4

3 に答える 3

1

my-secret-keyは有効な Base64 文字列ではありません。signWith(SignatureAlgorithm, String)メソッドのJavaDocを読んでください:

/**
 * Signs the constructed JWT using the specified algorithm with the
 * specified key, producing a JWS.
 *
 * <p>This is a convenience method: the string argument is first
 * BASE64-decoded to a byte array and this resulting byte array is 
 * used to invoke {@link #signWith(SignatureAlgorithm, byte[])}.</p>
 *
 * @param alg the JWS algorithm to use to digitally sign the JWT, 
 *            thereby producing a JWS.
 * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific 
 *        signing key to use to digitally sign the JWT.
 * @return the builder for method chaining.
 */
JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey);

暗号化署名は常にバイト配列キーで計算されます - 文字列ではありません。たとえば、文字列の UTF-8 バイトを取得できます、これは非常に問題のある暗号化の弱点を"my-secret-key".getBytes("UTF-8");覆い隠すだけです。

デジタル署名キー (ここでもバイト配列) は、理想的には、'my secret' や 'my password' などの単純な文字列に基づくべきではありません。または、少なくとも、単純なパスワードを署名キーとして使用する必要がある場合は、ほとんどの場合、キー導出アルゴリズム (PBKDF2 など) を介して送信し、その結果の出力を署名キーとして使用する方が適切です。これにより、人間が読める短い文字列にはない (したがって危険な) 十分な暗号化エントロピー (ランダム性) が確保されます。

署名鍵は、理想的には常に次のようにする必要があります。

  1. 安全な乱数ジェネレーターによって生成されるか、少なくとも暗号的に安全なキー導出関数を介して作成され、
  2. これは重要です。ハッシュアルゴリズムを使用するのに十分な長さです。

番号 2 は、JJWT がMacProvider.generateKeyメソッドを提供する理由です。選択したアルゴリズムに対して十分な強度のキーを常に確保するためです。その後、結果を簡単に base64 にできます。

SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256);
String base64Encoded = TextCodec.BASE64.encode(key.getEncoded());

これが、JJWT がデフォルトで Base64 を想定している理由です。これらのベスト プラクティスを実行すると、常にバイト配列キー (key.getEncoded() など) になるためです。また、バイト配列キーがある場合、それを文字列に変換する最も一般的な方法 (構成など) は、そのバイト配列を Base64 エンコードすることです。

TextCodec.BASE64.decode(myKey)最後に、は と同じバイト配列 (キー) を生成しないことに注意してくださいmyKey.getBytes('UTF-8')。後者は通常、暗号化コンテキストでは正しくありません。

これは、my-secret-token-to-change-in-production.getBytes("UTF-8") が弱められた署名キーを表している可能性があることを意味し、結果として使用すべきではありません。その現在のキーをダンプし、上記のように (JJWT などを使用して) 強力な暗号化保証を備えた新しいキーを生成し、Node ライブラリが文字列を正しく base64 デコードするようにすることをお勧めします。

したがって、安全なランダム生成バイト配列と Base64 を取得したら、上記のツールで「秘密の base64 エンコード」チェックボックスをオンにすると、うまくいくはずです。

于 2016-10-07T22:44:46.307 に答える
1

Java でトークンを作成しているため、トークンの作成が組み込まれている公式の Firebase Java SDK を利用できます。こちらの手順とコード サンプルに従って、カスタム トークンの作成を開始してください。

あなたの主な問題は、HS256 暗号化でトークンを作成していることだと思いますが、Firebase には RS256 が必要です。しかし、公式ライブラリを使用すると、これらすべてが処理されます。

于 2016-10-10T21:13:56.497 に答える
0

iatPHP JWTジェネレーターライブラリで同様の問題があり、解決策はペイロードパラメーターで遊んでいました。私のサーバーは、Googleのサーバーと比較して数秒先でした(エラーメッセージはそれを教えてくれませんでした...)。

iat過去5分でペイロードパラメーターを定義したところ、ブームになりました。

これが役立つことを願っています。

于 2017-03-05T11:18:01.243 に答える