vb.net - 授权码验证(OpenID Connect 1.0)
问题描述
我尝试按照以下步骤验证授权码:
要使用 ID 令牌验证从授权端点发出的授权代码,客户端应该执行以下操作:
1-)使用 JWA [JWA] 中为 ID 令牌的 JOSE 标头的 alg 标头参数指定的散列算法对代码的 ASCII 表示的八位字节进行散列。例如,如果 alg 是 RS256,则使用的哈希算法是 SHA-256。
2-)取散列的最左半部分,base64url 对其进行编码。
3-)如果 c_hash 存在于 ID 令牌中,则 ID 令牌中的 c_hash 值必须与上一步中生成的值匹配。
当我第一次请求授权端点以尝试从 WebForms 客户端对用户进行身份验证时,我有此代码:
code=0655d48df75629d9fdbd5a060141bf66ca04418a0e762a6a5e6382c2748753af
我也有这个 C_HASH ,我可以从 id_token 获得:
"c_hash": "QadHSCSim4aHM8q1F1F6Bg"
我正在尝试验证下一个代码:
Private Shared Function IsValidAuthorizationCode(authorizationCode As String, stringIdTokenPayload As String) As Boolean
Dim serializer As New JavaScriptSerializer()
Dim BytesPayload As Byte() = Decode(stringIdTokenPayload)
Dim stringPayload As String = System.Text.ASCIIEncoding.ASCII.GetString(BytesPayload)
Dim deserialized_payload = serializer.Deserialize(Of Dictionary(Of String, Object))(stringPayload)
Dim c_hash = deserialized_payload.Item("c_hash").ToString()
Dim mySHA256 = SHA256Managed.Create()
Dim authorizationCodeOCTETS = Decode(authorizationCode)
Dim elemntsToIterate = mySHA256.ComputeHash(authorizationCodeOCTETS)
Dim length = elemntsToIterate.Length
Dim hashedCode(length/2 - 1) As Byte
Dim count = -1
For Each element As Byte in elemntsToIterate
count += 1
If count > 15 Then
hashedCode(count - 16) = element
End If
Next
Dim hashedCodeLikeString = Convert.ToBase64String(hashedCode)
If hashedCodeLikeString.Length <> hashedCode.Length
Return False
Dim result As Boolean = True
For value As Integer = 0 To hashedCodeLikeString.Length
If (hashedCodeLikeString(value) <> hashedCode(value)) Then
result = False
Exit For
End If
Next
Return result
End Function
但我没有得到预期的结果。我需要得到一个 TRUE 值,但我得到一个 FALSE。我认为我做错了什么,但我不明白它是什么。请问有什么帮助吗?
非常感谢您提前。
解决方案
我不知道你的这种编程语言,但这是来自 OidcClient 的代码
https://github.com/IdentityModel/IdentityModel.OidcClient2
public bool ValidateHash(string data, string hashedData, string signatureAlgorithm)
{
var hashAlgorithm = GetMatchingHashAlgorithm(signatureAlgorithm);
using (hashAlgorithm)
{
var hash = hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(data));
byte[] leftPart = new byte[hashAlgorithm.HashSize / 16];
Array.Copy(hash, leftPart, hashAlgorithm.HashSize / 16);
var leftPartB64 = Base64Url.Encode(leftPart);
var match = leftPartB64.Equals(hashedData);
if (!match)
{
_logger.LogError($"data ({leftPartB64}) does not match hash from token ({hashedData})");
}
return match;
}
}
public HashAlgorithm GetMatchingHashAlgorithm(string signatureAlgorithm)
{
var signingAlgorithmBits = int.Parse(signatureAlgorithm.Substring(signatureAlgorithm.Length - 3));
switch (signingAlgorithmBits)
{
case 256:
_logger.LogDebug("SHA256");
return SHA256.Create();
case 384:
_logger.LogDebug("SHA384");
return SHA384.Create();
case 512:
_logger.LogDebug("SHA512");
return SHA512.Create();
default:
return null;
}
}
推荐阅读
- websphere - 如何使用 Jython 获取所有 websphere 应用程序配置?
- ios - 如何在静态表视图上设置协议和委托?
- azure - 如何在 Azure HDInsight 群集中创建 Pig Latin 作业
- entity-framework-core - EF Core 3.1:更新单条记录
- sqlite - SQLite,用 TEXT 值填充 NULL
- python-3.x - 为什么在 aiohttp 中使用 https 而不是 http 时会有这么多开销
- git - 有没有办法在 macOS 上使用智能卡连接到 GIT HTTPS 站点?
- c# - 在 JSON 中添加自定义标头
- python - 跨度上的 BeautifulSoup get_text() 方法将引号作为字符串的一部分返回
- html - 使用 laravel 插入 Select