基于RSA公钥大小拒绝相互TLS gRPC连接

问题描述 投票:5回答:1

我有一台gRPC服务器,该服务器正在使用相互TLS进行加密和身份验证。因此,每个连接到该服务器的客户端都提供一个SSL证书,我想从公共密钥大小小于2048位的客户端中<。似乎还没有直接的方法可以做到这一点。

我可以通过ServerInterceptor这样操作

public class SSLInterceptor implements ServerInterceptor { @Override public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> 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 } ... } }

这是一种不好的方法,因为

    已经在连接之后进行验证建立的。
  1. 仅在发出请求/调用时才触发验证。
  2. 每个呼叫都涉及额外的验证开销。
  3. 如果验证失败,则仅拒绝呼叫,而不拒绝与客户端的连接。
  • 在理想情况下

      验证是在连接建立阶段完成的。 (或在客户端和服务器之间的通道创建过程中的某个时间点)
  • 验证失败将阻止建立连接,并且无法建立连接并稍后断开连接。
  • 每个会话仅对客户端进行一次验证,并且在该会话期间进行的所有调用都不会产生任何开销。
  • 我该如何做得更好?
  • validation ssl grpc public-key grpc-java
    1个回答
    0
    投票
    您可以通过向Netty的javax.net.ssl.TrustManagerFactory提供自己的SslContextBuilder来自定义证书检查。您可能想要实现X509ExtendedTrustManager,进行检查,然后委派给“真实”实现,以进行其余的证书链检查。

    您可以执行类似的操作以获取默认配置TrustManagerFactory

    TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); tmf.init((KeyStore) null); // loop through tmf.getTrustManagers() checking for one implementing X509TrustManager

    © www.soinside.com 2019 - 2024. All rights reserved.