• keycloak~jwt的rs256签名的验证方式


    接口地址

    • keycloak开放接口地址:/auth/realms/fabao/.well-known/openid-configuration

    rsa算法相关术语

    RSA算法是一种非对称加密算法,其安全性基于大整数分解的困难性。在RSA算法中,有以下几个关键参数:

    1. n(模数):n 是一个大整数,通常为两个大素数 p 和 q 的乘积,即 n = p * q。n 用于生成公钥和私钥,并且决定了加密和解密的计算过程。

    2. e(公钥指数):e 是一个与 φ(n) 互质的小整数,其中 φ(n) 是欧拉函数,表示小于 n 且与 n 互质的正整数的个数。e 在加密时使用,作为公钥的一部分。

    3. 公钥:公钥由 (n, e) 组成,其中 n 是模数,e 是公钥指数。公钥用于加密消息,任何人都可以获得公钥进行加密操作。

    4. 私钥:私钥由 (n, d) 组成,其中 n 是模数,d 是私钥指数。私钥用于解密已经被公钥加密的消息,只有私钥的持有者才能获得解密能力。

    总结来说,RSA算法通过公钥加密、私钥解密的方式实现信息的安全传输,公钥用于加密数据,私钥用于解密数据;反过来,私钥可以用来生成签名,而公钥可以用来验证签名的有效性。

    RSA和RS256

    1. RSA:RSA是一种非对称加密算法,可以用于数据的加密和数字签名。在RSA中,公钥和私钥是成对存在的,公钥用于加密数据或验证数字签名,私钥用于解密数据或生成数字签名。

    2. RS256:RS256是一种基于RSA算法的数字签名算法,其中“RS”代表RSA算法,“256”表示使用SHA-256哈希算法生成摘要。RS256常用于JWT(JSON Web Token)的数字签名过程中,用于验证数据的完整性和真实性。

    因此,可以说RS256是RSA算法的一种特定应用,用于数字签名,并且结合了SHA-256哈希算法。RSA算法还可以用于加密数据等其他用途,而RS256主要用于数字签名。

    获取keycloak颁发的公钥

    • 从jwks公钥开放地址获取公钥 /auth/realms/fabao/protocol/openid-connect/certs

    • 从keycloak后台获取公钥

    keycloak中jwt的验证

    • 在客户端验证keycloak的token是否在传输过程中被篡改,即签名验证是否通过
    • 下面代码中定义了公钥字符串,从开放地址返回的rsa公钥的n模数和e指数
    • 从kecloak认证中心颁发的公钥字符串
    • 从现在有keycloak认证中心获取的jwt字符串
    // RSA公钥的模数
    String modulus = "yOCNCy8x280...";
    
    // RSA公钥的指数
    String exponent = "AQAB";
    
    // keycloak拿到的公钥
    String publicKeyString = "MIIBIjANBg...B";
    
    String KcJwtToken = "eyJh...";
    
    
    • 根据公钥开放地址返回的公钥信息n和e来验证签名
    @Test
    public void verifySign() throws Exception {
    	String[] jwtParts = KcJwtToken.split("\\.");
    	String header = jwtParts[0];
    	String payload = jwtParts[1];
    	// 解码Base64格式的模数和指数
    	byte[] decodedModulus = Base64.getUrlDecoder().decode(modulus);// getMimeDecoder()会忽略非Base64字符(如换行符、空格等)
    	byte[] decodedExponent = Base64.getUrlDecoder().decode(exponent);
    	// 构建RSA公钥对象
    	RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(new BigInteger(1, decodedModulus),
    			new BigInteger(1, decodedExponent));
    	// 验征RSA签名
    	PublicKey publicKey = KeyFactory.getInstance("rsa").generatePublic(publicSpec);
    	boolean result = RSAUtils.verify(header + "." + payload, publicKey, jwtParts[2]);
    	System.out.print("验签结果:" + result);
    
    }
    
    • 根据keycloak后台颁发的公钥字符串来验证签名
    // 根据认证平台颁发的公钥字符串来验证签名
    @Test
    public void verifyJwtToken() throws Exception {
    	String[] jwtParts = KcJwtToken.split("\\.");
    	String header = jwtParts[0];
    	String payload = jwtParts[1];
    	String sign = jwtParts[2];
    	PublicKey publicKey = RSAUtils.getPublicKey(publicKeyString);
    	boolean result = RSAUtils.verify(header + "." + payload, publicKey, sign);
    	System.out.print("验签结果:" + result);
    }
    

    需要注意的是,以上jwt的token签名使用rs256(SHA256withRSA)算法生成的签名,所以本例子都是采用这种签名算法实现的,例外,也有h256,h512等哈希算法。

    keycloak支持的签名算法

    public static final String RS256 = "SHA256withRSA";
    public static final String RS384 = "SHA384withRSA";
    public static final String RS512 = "SHA512withRSA";
    public static final String HS256 = "HMACSHA256";
    public static final String HS384 = "HMACSHA384";
    public static final String HS512 = "HMACSHA512";
    public static final String ES256 = "SHA256withECDSA";
    public static final String ES384 = "SHA384withECDSA";
    public static final String ES512 = "SHA512withECDSA";
    public static final String PS256 = "SHA256withRSAandMGF1";
    public static final String PS384 = "SHA384withRSAandMGF1";
    public static final String PS512 = "SHA512withRSAandMGF1";
    public static final String AES = "AES";
    
    public static final String SHA256 = "SHA-256";
    public static final String SHA384 = "SHA-384";
    public static final String SHA512 = "SHA-512";
    
  • 相关阅读:
    [ vulhub漏洞复现篇 ] Thinkphp SQL注入 && 敏感信息泄露
    浅谈基于云计算的环境智能监控系统
    Linux初级知识大全(一)
    qemu-img操作文件出现“Could not read snapshots: File too large”问题解决办法
    2022年暑期及9月份CSP-J1 CSP-S1初赛 培训计划及学习要点
    【剑指Offer】10.斐波那契数列
    MySQL的内置函数
    selenium模块使用详解、打码平台使用、xpath使用、使用selenium爬取京东商品信息、scrapy框架介绍与安装
    Vuex使用一文搞懂
    基于JavaSpringBoot+Vue+uniapp实现校园宿舍管理系统
  • 原文地址:https://www.cnblogs.com/lori/p/18143424