我有一台使用相互TLS进行加密和身份验证的gRPC服务器。因此,每个连接到该服务器的客户端都提供一个SSL证书,我想拒绝来自公共密钥大小小于2048位的客户端的连接。似乎还没有直接的方法可以做到这一点。
我能够用ServerInterceptor
这种方式做到这一点
public class SSLInterceptor implements ServerInterceptor {
@Override
public Listener interceptCall(ServerCall call, Metadata headers, ServerCallHandler next) {
try {
SSLSession sslSession = call.getAttributes().get(Grpc.TRANSPORT_ATTR_SSL_SESSION);
RSAPublicKeyImpl pk = (RSAPublicKeyImpl) sslSession.getPeerCertificates()[0].getPublicKey();
if (pk.getModulus().bitLength() <2048) {
// reject call
}
// proceed with the call
} catch (SSLPeerUnverifiedException e) {
// do something
}
...
}
}
这是一个不好的方法,因为
在建立连接之后进行验证。
仅当发出请求/调用时才触发验证。
每个调用都涉及额外的验证开销。
如果验证失败,则仅拒绝呼叫,而不拒绝与客户端的连接。
在理想情况下
验证在连接建立阶段完成。(或在客户端和服务器之间的通道创建过程中的某个时间点)
验证失败将阻止创建连接,并且无法建立连接并稍后断开连接。
每个会话仅对客户端进行一次验证,并且在该会话期间进行的所有调用都不会产生任何开销。
我该如何做得更好?