Java从YAML读取RSA公钥验证JWT抛InvalidKeyException的解决
解决YAML读取RSA公钥导致JWT验证失败的问题
你碰到的这个问题我之前也踩过坑!核心原因是YAML里的>符号在搞事情——它属于折叠块标量,会把多行文本里的换行符全部替换成空格,最终输出一个没有换行的单行字符串。但RSA公钥的格式要求严格,必须保留每行的换行符才能被JWT验证库正确解析,所以直接读取就会抛出InvalidKeyException。
下面给你两个靠谱的解决办法:
方法一:修改YAML配置文件(推荐)
把>换成|(字面块标量),它会完整保留所有换行符,和你硬编码的格式完全一致:
http_authenticator: type: jwt challenge: false config: signing_key: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApJubKdzjmxriryviTEPN 85qX8SzcDbseBjJXJzrt3Xn0mk7+7ZxWDnB5Qh/TvZoHGOcaVeoRIzBi1AdX20az x7oAzfMLI48sDEptwJgd87Mg6UmvXlPOkvRypUSP8pFrOUg+aQ75qRsQkXBBWMIO qBZiDXVrMHY1+Q1LOJR1aWFjIlL1WNZecTNJ9UfPhjxW7WJRmI3/EXPbD/OEeC7J mD/nifofYUQUavggcirKI0KM17ENLdyZy3aWfpKOXqZJByfbp5AXmWoWcNZqsiHy KL/sK/nmX86jwKRHvIOQv9IBlPCNSxNr6IQox/BHqZssvY2J65UHOaTJ408x7IQT FQIDAQAB -----END PUBLIC KEY----- jwt_header: "Authorization" jwt_url_parameter: null cookieName: "Cookie" cookieHeaderName: "jwt_token"
修改后直接读取signing_key,得到的字符串就和你硬编码的版本一模一样,不需要额外处理就能正常验证JWT。
方法二:在代码中手动修复换行(如果不能改YAML)
如果没办法修改配置文件,就在读取到字符串后手动把空格替换回换行符(因为YAML的>把换行转成了空格):
String signingKey = settings.get("signing_key"); // 替换所有空格为换行符,还原公钥格式 signingKey = signingKey.replace(" ", "\n");
或者用更严谨的正则表达式,按RSA公钥每行64字符的规则插入换行:
String signingKey = settings.get("signing_key"); // 先去掉首尾的空格,再按64字符拆分插入换行 signingKey = signingKey.trim().replaceAll("(.{64})", "$1\n"); // 确保BEGIN和END行单独成行 signingKey = "-----BEGIN PUBLIC KEY-----\n" + signingKey + "\n-----END PUBLIC KEY-----";
补充:YAML块标量小知识
>:折叠模式,所有换行变为空格,仅保留最后一个换行|:字面模式,完全保留所有换行符,是存储多行代码/密钥的最佳选择
内容的提问来源于stack exchange,提问作者summerNight




