解码 Base64urlUInt 编码的值

Posted

技术标签:

【中文标题】解码 Base64urlUInt 编码的值【英文标题】:Decoding Base64urlUInt-encoded value 【发布时间】:2016-03-20 23:35:39 【问题描述】:

我通常尝试做的是验证从 OpenID Connect 提供商(例如 Google)获得的 id_token 值。令牌使用 RSA 算法签名,公钥从 Discovery 文档(jwks_uri 参数)中读取。例如,Google 密钥以 JWK 格式提供 here:


  kty: "RSA",
  alg: "RS256",
  use: "sig",
  kid: "38d516cbe31d4345819b786d4d227e3075df02fc",
  n: "4fQxF6dFabDqsz9a9-XgVhDaadTBO4yBZkpUyUKrS98ZtpKIQRMLoph3bK9Cua828wwDZ9HHhUxOcbcUiNDUbubtsDz1AirWpCVRRauxRdRInejbGSqHMbg1bxWYfquKKQwF7WnrrSbgdInUZPv5xcHEjQ6q_Kbcsts1Nnc__8YRdmIGrtdTAcm1Ga8LfwroeyiF-2xn0mtWDnU7rblQI4qaXCwM8Zm-lUrpSUkO6E1RTJ1L0vRx8ieyLLOBzJNwxpIBNFolMK8-DYXDSX0SdR7gslInKCn8Ihd9mpI2QBuT-KFUi88t8TW4LsoWHAwlgXCRGP5cYB4r30NQ1wMiuQ",
  e: "AQAB"

我将使用RSACryptoServiceProvider 类来解码签名。要初始化它,我必须为RSAParameters 提供模数和指数值。这些值从上述 JWK 中读取为对应的 ne。根据specification,这些值是Base64urlUInt编码的值:

将正整数或零整数值表示为 值的无符号大端表示的 base64url 编码 作为八位字节序列。八位字节序列必须使用最小的 表示值所需的八位字节数。零表示 作为 BASE64URL(单个零值八位字节),即“AA”。

那么,我的问题是如何解码这些值以将它们放入 RSAParameters?我尝试将它们解码为常见的 Base64url 字符串 (Convert.FromBase64String(modulusRaw)),但这显然不起作用并生成此错误:

输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或非法字符 在填充字符之间。

【问题讨论】:

HttpServerUtility.UrlTokenDecode 不适用于您的情况吗? @Baldrick 谢谢!但是,这在这种情况下不起作用。 【参考方案1】:

RFC 7515 定义 base64url 编码如下:

使用 URL 和文件名安全字符集的 Base64 编码 在RFC 4648 的第 5 节中定义,所有尾随 '=' 省略的字符(如第 3.2 节所允许的)并且没有 包含任何换行符、空格或其他额外的 人物。注意空八位字节的base64url编码 序列是空字符串。 (见附录 C 的注释 实现 base64url 编码而不进行填充。)

RFC 4648 将“使用 URL 和文件名安全字母的 Base 64 编码”定义为常规 base64,但是:

可以省略填充(就像这里一样) 使用- 代替+_ 代替/

所以要使用普通的Convert.FromBase64String,你只需要反转这个过程:

static byte[] FromBase64Url(string base64Url)

    string padded = base64Url.Length % 4 == 0
        ? base64Url : base64Url + "====".Substring(base64Url.Length % 4);
    string base64 = padded.Replace("_", "/")
                          .Replace("-", "+");
    return Convert.FromBase64String(base64);

这段代码可能已经存在于框架的某个地方,但我不知道。

【讨论】:

【参考方案2】:

谁从 Java 来到这里:java.util.Base64 中有两种方法:

getDecoder() getUrlDecoder()

正如您可能假设的那样:使用第二个已经为您完成了所有字符替换。

【讨论】:

以上是关于解码 Base64urlUInt 编码的值的主要内容,如果未能解决你的问题,请参考以下文章

JSON 编码/解码 JavaScript 中的 base64 编码/解码

前端base64编码与解码

Go语言实现Base64Base58编码与解码

base64编码与base64解码

2018-07-17 Base64解码与编码

LoadRunner中Base64编码解码