当前位置:  开发笔记 > 编程语言 > 正文

解码Base64urlUInt编码的值

如何解决《解码Base64urlUInt编码的值》经验,为你挑选了1个好方法。

我通常想做的是验证从OpenID Connect提供程序(例如Google)获得的id_token值。令牌使用RSA算法签名,并且从发现文档(jwks_uri参数)读取公共密钥。例如,此处以JWK格式提供Google密钥:

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

我将使用RSACryptoServiceProvider类来解码签名。要初始化它,我必须为RSAParameters提供Modulus和Exponent值。这些值从上述JWK中分别读取为ne。根据规范,这些值是Base64urlUInt编码的值:

正或零整数值的表示形式,以值的无符号big-endian表示形式的八位字节序列的base64url编码。八位位组序列必须使用表示该值所需的最少八位位组数。零表示为BASE64URL(单个零值八位位组),即“ AA”。

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

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

Jon Skeet.. 5

RFC 7515定义了base64url编码,如下所示:

使用RFC 4648第5节中定义的URL和文件名安全字符集进行的Base64编码,省略了所有结尾的'='字符(如第3.2节所允许),并且不包含任何换行符,空格或其他附加字符。请注意,空字节序列的base64url编码是空字符串。(有关不进行填充而实现base64url编码的说明,请参阅附录C。)

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

可以省略填充(如此处所示)

使用-代替+_代替/

因此,要使用normal 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);
}

该代码可能已经存在于框架中的某个位置,但是我不知道。



1> Jon Skeet..:

RFC 7515定义了base64url编码,如下所示:

使用RFC 4648第5节中定义的URL和文件名安全字符集进行的Base64编码,省略了所有结尾的'='字符(如第3.2节所允许),并且不包含任何换行符,空格或其他附加字符。请注意,空字节序列的base64url编码是空字符串。(有关不进行填充而实现base64url编码的说明,请参阅附录C。)

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

可以省略填充(如此处所示)

使用-代替+_代替/

因此,要使用normal 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);
}

该代码可能已经存在于框架中的某个位置,但是我不知道。

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有