我能够在Azure AD身份验证中请求令牌。但是问题是,每当我更改access_token中的最后一个字符时,它仍会在我的API中成功请求。我只是遵循这个https://mehmetkut.com/2017/05/protect-aspnetcore-webapi-resources-with-azure-active-directory-en/,有没有一种方法可以验证令牌?仅当我至少更改了最后一个字符中的一个时,才会发生这种情况。
https://mehmetkut.com/2017/05/protect-aspnetcore-webapi-resources-with-azure-active-directory-en/
即使我更改了最后一个字符,令牌仍然有效。
答案 0 :(得分:5)
有趣的是,我们在安全审核中也做到了这一点。
事实证明,签名的后4位只是填充,并不属于签名的一部分。 因此某些字符将被接受为最后一个字符,而不是全部。 在这种情况下,您实际上并没有修改签名数据,只需填充。
这是比我聪明的人的解释:
这是base64解码的副作用,即解码后的事实 签名的长度为256个字节,而剩下的256个事实 1除以3。?
RS256 alg值对应于“ RSASSA-PKCS1-v1_5使用 SHA-256”算法,其签名为256个字节 然后在构造JWT时将base64url编码为long, 结果是第二个“。”之后的342个字符。前255个字节 所有未编码的签名都很好地适合340个字符 base64(每6位输入产生1个编码字符)。来自 签名的最后一个字节,前6位为第341个字符 编码签名。现在我们只剩下两位要编码。 由于我们需要6位来获取base64编码的字符,因此我们追加了 四个0给我们6位,并按常规进行编码。
解码时,我们从左侧开始,将每个字符转换为 二进制的base64索引(例如,“ A”为000000,“ B”为000001,“ C”为 000010等),然后抓取8位的组以构成已解码的字节 输入。从以base64编码的数据的前340个字符中,我们得到 原始数据的前255个字节(签名字节)。这个 剩下12位。我们抓取8位以形成第256个字节 原始输入,并且由于没有足够的位数来形成 一个完整的字节,我们只丢弃最后4位(请记住,这4位 是我们在编码时“填充”的0。)
由于仅丢弃了最后4位(它们不属于 编码的签名,它们只是用于填充),这4位 实际上可以是任何东西。后6位中只有前两位 实际上是原始消息的一部分。
这确实很难用文字解释,但是如果您 自己尝试一下:只需手动将单个字节编码为Base64, 然后将其解码。
以您的示例为例,如果最后一个base64字符为“ A”,则为 base64索引为0(000000)。字符“ B”至“ P”对应 到base64索引1(000001)到15(001111)。在所有 这些,前两位总是00。由于后四位是 将被丢弃),您可以选择从A到P的任何内容,然后 不会对真正重要的两个部分产生任何影响。如果你走的话 改为“ Q”,索引为16(010000),现在您已经更改了这两个之一 消息中的几位,并且签名不再有效。