URL 编码后,数字 1 随机附加到我的 JWT 密码的末尾
Posted
技术标签:
【中文标题】URL 编码后,数字 1 随机附加到我的 JWT 密码的末尾【英文标题】:Number 1 is randomly appended to the end of my JWT secret after URL encoding 【发布时间】:2018-08-17 03:39:25 【问题描述】:我已经在每个角落和缝隙中寻找解决问题的方法,但我似乎找不到。
我有一个利用方法创建 JSON Web 令牌的类。我创建的 Web 令牌需要与以下内容匹配(请注意,我的密钥最右侧没有数字 1):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBrZXkiOiIxMjMtNDU2LTc4OS0wIiwicmVzb3VyY2UiOiJnZXRfZ2VvY29kZSJ9.xGLb92d6yVLqLf5TnrahMCxm-OGTHmXiXLvnRUqLWYM
我生成的令牌与上面的令牌匹配,除了数字 1 随机附加在令牌的最右端:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBrZXkiOiIxMjMtNDU2LTc4OS0wIiwicmVzb3VyY2UiOiJnZXRfZ2VvY29kZSJ9.xGLb92d6yVLqLf5TnrahMCxm-OGTHmXiXLvnRUqLWYM1
如您所见,这是 JWT 中保存秘密的部分。让我演示一下我是如何生成和加密令牌的,以便您帮助诊断问题。我将向您展示整个课程,然后引导您完成这些方法。
这是整个班级:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Security.Cryptography;
namespace Project.JWT
public class Token
public string CreateToken(string resource, string appkey, string secret, string algorithm)
if (algorithm != "HS256")
return "Algorithm not supported";
JwtPayload payload = new JwtPayload
appkey = appkey,
resource = resource
;
return EncodeToken(payload, secret);
public static string EncodeToken(JwtPayload jwtPayload, string secret)
const string algorithm = "HS256";
var header = new Header
typ = "JWT",
alg = algorithm
;
var jwt = Base64Encode(JsonConvert.SerializeObject(header)) + "." + Base64Encode(JsonConvert.SerializeObject(jwtPayload));
jwt += "." + Sign(jwt, secret);
return jwt;
public static string Base64Encode(dynamic obj)
Type strType = obj.GetType();
var base64EncodedValue = Convert.ToBase64String(strType.Name.ToLower() == "string" ? Encoding.UTF8.GetBytes(obj) : obj);
return base64EncodedValue;
private static string Sign(string str, string key)
byte[] signature;
using (var crypto = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
signature = crypto.ComputeHash(Encoding.UTF8.GetBytes(str));
return System.Web.HttpServerUtility.UrlTokenEncode(signature);
public class Header
public string alg get; set;
public string typ get; set;
public class JwtPayload
public string appkey get; set;
public string resource get; set;
首先,向 CreateToken 方法传递凭据以创建有效负载。然后它调用将有效负载和机密作为参数的 EncodeToken 方法。请记住,我的秘密是一个硬编码的字符串,在应用程序的整个生命周期中都不会改变;所以我知道这不是随机生成数字 1。
第 39 行,标头和有效负载被转换为 base 64 字符串,并由一个点连接在一起,完美地生成了我的令牌的前两部分:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBrZXkiOiIxMjMtNDU2LTc4OS0wIiwicmVzb3VyY2UiOiJnZXRfZ2VvY29kZSJ9
然后,我在第 41 行调用 Sign 方法,该方法请求使用 SHA256 算法对我的令牌进行签名。
Sign 方法接受组合的标头和有效负载作为 str,然后秘密作为密钥传递。
在第 62 行,我使用自定义密钥“testsecret”开始创建签名。
然后我在第 67 行对签名进行 URL 编码,就在返回之前。当我返回它时,第 41 行将令牌的三个部分组合在一起,从而给我留下了一个完美的 JWT……除了密钥最右端的数字“1”。
请帮忙。
【问题讨论】:
【参考方案1】:这与HttpServerUtility.UrlTokenEncode 的工作方式有关,强调我的:
使用基本 64 位数字将字节数组编码为其等效的字符串表示,可用于在 URL 上传输
您会知道,根据其长度,Base64 字符串将在末尾添加=
。 =
不被认为是 URL 安全的,因此被替换为表示计数的整数,在本例中为 1
。
您可以通过调试和替换下面的行来测试这个...
return System.Web.HttpServerUtility.UrlTokenEncode(signature);
...用这个...
return Convert.ToBase64String(signature);
...并检查返回值。
您会看到它以=
结尾,因此HttpServerUtility.UrlTokenEncode
将其替换为1
。
【讨论】:
以上是关于URL 编码后,数字 1 随机附加到我的 JWT 密码的末尾的主要内容,如果未能解决你的问题,请参考以下文章