升级.Net8后Jwt密钥长度要求大于32的问题

原因

  前段时间将项目升级到.net8后,提示jwt密钥长度太短了,这咋办,我

解决

  1.  最简单的办法,把密钥长度加长

  2.  如果你的项目只需要验证token,而不需要生成,就:

  

SymmetricSecurityKey ExtendKeyLengthIfNeeded(SymmetricSecurityKey key, int minLenInBytes) {
    if (key != null && key.KeySize < (minLenInBytes * 8)) {
        var newKey = new byte[minLenInBytes]; // zeros by default
        key.Key.CopyTo(newKey, 0);
        return new SymmetricSecurityKey(newKey);
    }
    return key;
}
// 添加jwt服务时加到jwt配置里去
jwtParams.IssuerSigningKeyResolver = (tokenString, securityToken, identifier, parameters) => { string alg = null; if (securityToken is JwtSecurityToken jwtSecurityToken) alg = jwtSecurityToken.SignatureAlgorithm; if (securityToken is Microsoft.IdentityModel.JsonWebTokens.JsonWebToken jsonWebToken) alg = jsonWebToken.Alg; if (parameters.IssuerSigningKey is SymmetricSecurityKey symIssKey && alg!=null) { // workaround for breaking change in "System.IdentityModel.Tokens.Jwt 6.30.1+ switch (alg?.ToLowerInvariant()) { case "hs256": return new[] { ExtendKeyLengthIfNeeded(symIssKey, 32) }; case "hs512": return new[] { ExtendKeyLengthIfNeeded(symIssKey, 64) }; } } return new[] { parameters.IssuerSigningKey };
};

  这个方法来源于下面这个连接,如果有不理解的可以研究

  来源:c# - Migrating existing API project to .NET 8 getting error when creating JWT tokens - Stack Overflow

  3.  如果你的项目既要还要,那就:

  那就要研究以下源码了,大概翻了下哪里会抛出” IDX10720 “ 异常,发现只有一个地方

  这段代码太多就不展示了,有时间可以自己去看

  抛异常的源码地址:azure-activedirectory-identitymodel-extensions-for-dotnet/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs at c24bfe683427dbad566fe617d0d590ec3a61d8aa · AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet (github.com)

  看了代码后发现是可以绕过检查的,可以自定义一个加密类型,这样就管不着了

  下面这段代码定义了一个加密方法,其实还是用的HmacSha256,就为了跳过检查

public class ShortHS256KeyCryptoProvider : ICryptoProvider
{
    public object Create(string algorithm, params object[] args)
    {
        if (args is null || args.Length == 0)
            return null;
        if (args[0] is SecurityKey)
            return null;
        if (!algorithm.Equals(SecurityAlgorithms.HmacSha256Signature, StringComparison.OrdinalIgnoreCase)
            && !algorithm.Equals(SecurityAlgorithms.HmacSha256, StringComparison.OrdinalIgnoreCase))
            return null;

        return new HMACSHA256(args[0] as byte[]);
    }

    public bool IsSupportedAlgorithm(string algorithm, params object[] args)
    {
        if(args is null || args.Length == 0)
            return false;
        if (args[0] is SecurityKey)
            return false;
        if(!algorithm.Equals(SecurityAlgorithms.HmacSha256Signature, StringComparison.OrdinalIgnoreCase)
            && !algorithm.Equals(SecurityAlgorithms.HmacSha256, StringComparison.OrdinalIgnoreCase))
            return false;
        return true;
    }

    public void Release(object cryptoInstance)
    {
        if (cryptoInstance is IDisposable disposableObject)
            disposableObject.Dispose();
    }
}

  然后在找个地方把自定义的加密添加到jwt里面去,就下面这句代码:

CryptoProviderFactory.Default.CustomCryptoProvider = new ShortHS256KeyCryptoProvider();

  最后收工!!!

 

  

 

posted @ 2024-06-21 16:43  该昵称已被屏蔽  阅读(245)  评论(0)    收藏  举报