[英]Firebase Custom Auth Error: The custom token format is incorrect
我正在使用這樣的 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();
該密鑰(“我的秘密鑰匙”),我使用的是由火力地堡產生,如前所述這里
但是當我使用如上生成的令牌登錄 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)
這是它的解碼方式 -
請幫助,提前致謝。
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");
,但這只能掩蓋可能是一個非常有問題的加密弱點。
數字簽名密鑰(再次,字節數組),理想情況下不應基於簡單的字符串,如“我的秘密”或“我的密碼”。 或者,至少,如果一個簡單的密碼應該用作簽名密鑰,那么通過密鑰派生算法(如 PBKDF2)發送它,然后將結果輸出用作簽名密鑰幾乎總是更好。 這確保了足夠的密碼熵(隨機性),而短的、人類可讀的字符串則沒有(因此有風險)。
理想情況下,簽名密鑰應始終為:
第 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')
相同的字節數組(密鑰myKey.getBytes('UTF-8')
。 后者在加密上下文中通常是不正確的。
這意味着 my-secret-token-to-change-in-production.getBytes("UTF-8") 可能代表弱化的簽名密鑰,因此不應使用。 我建議轉儲該當前密鑰並生成一個具有強加密保證的新密鑰,如上所示(例如使用 JJWT),並確保您的 Node 庫 base64 正確解碼您的字符串。
所以,一旦你有一個安全的隨機生成的字節數組和 Base64,然后檢查上面工具中的“秘密 base64 編碼”復選框,它應該適合你。
我在 PHP JWT 生成器庫中遇到了類似的問題,解決方案是使用iat
負載參數。 與谷歌的服務器相比,我的服務器在未來幾秒鍾內(錯誤消息從未告訴我......)。
我剛剛在過去 5 分鍾定義了iat
有效載荷參數,然后就成功了。
希望這會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.