MINA SSHD使用OpenSSH证书认证触发InvalidKeyException的原因及自定义修改的隐患咨询
MINA SSHD使用OpenSSH证书认证触发InvalidKeyException的原因及自定义修改的隐患咨询
我在使用MINA SSHD时,自定义实现了PublickeyAuthenticator并注册到SSH服务器:
sshServer.setPublickeyAuthenticator(publicKeyAuth);
但当客户端使用OpenSSH证书(而非普通RSA公钥)进行认证时,触发了以下错误:
2024-12-25 17:29:30.882 sshd-SshServer[53600a30](port=2222)-nio2-thread-5 WARN org.apache.sshd.server.session.ServerUserAuthService.warn - handleUserAuthRequestMessage(ServerSessionImpl[null@/127.0.0.1:56562]) Failed (InvalidKeyException) to authenticate using factory method=publickey: Supplied key (org.apache.sshd.common.config.keys.OpenSshCertificateImpl) is not a RSAPublicKey instance
问题原因分析
经过调试定位,问题出在MINA SSHD的公钥签名验证初始化逻辑:
当客户端使用OpenSSH证书认证时,MINA SSHD传递给签名验证器的是OpenSshCertificateImpl类型的对象,而默认的RSA签名实现(SignatureRSA)的initVerifier方法会直接强制将传入的公钥转换为RSAKey类型,完全没有处理OpenSSH证书的场景——实际上OpenSshCertificateImpl内部封装了真实的RSA公钥,但默认逻辑没有做提取操作。
默认的SignatureRSA.initVerifier实现:
public void initVerifier(SessionContext session, PublicKey key) throws Exception { super.initVerifier(session, key); RSAKey rsaKey = ValidateUtils.checkInstanceOf(key, RSAKey.class, "Not an RSA key"); verifierSignatureSize = getVerifierSignatureSize(rsaKey); }
临时解决方法
我通过重写SignatureRSA的initVerifier方法,增加了对OpenSshCertificate类型的判断,从中提取出内部的真实RSA公钥再进行初始化,现在已经可以正常登录:
public void initVerifier(SessionContext session, PublicKey key) throws Exception { if (key instanceof OpenSshCertificate){ super.initVerifier(session, ((OpenSshCertificate) key).getCertPubKey()); RSAKey rsaKey = ValidateUtils.checkInstanceOf(((OpenSshCertificate) key).getCertPubKey(), RSAKey.class, "Not an RSA key"); verifierSignatureSize = getVerifierSignatureSize(rsaKey); }else { super.initVerifier(session, key); RSAKey rsaKey = ValidateUtils.checkInstanceOf(key, RSAKey.class, "Not an RSA key"); verifierSignatureSize = getVerifierSignatureSize(rsaKey); } }
待确认的疑问
- 为什么MINA SSHD的默认实现没有处理
OpenSshCertificateImpl的情况? - 我这种自定义修改方式存在哪些潜在的隐患?
备注:内容来源于stack exchange,提问作者鍒樺瓙鐟�,21"
相关产品推荐
相关产品推荐

