gRpc с аутентификацией клиента TLS с использованием SunPKCS11 в netty завершается неудачно
У меня есть приложение Java 8, использующее gRPC для сетевого общения. Чтобы обеспечить это, я использую TLS с аутентификацией клиента. Теперь я пытаюсь переключиться с программных ключей на смарт-карту с закрытым ключом и сертификатом (цепочкой) для аутентификации клиента. Мой код для создания netty внутри gRPC-провайдера sun pkcs#11 выглядит следующим образом:
static NettyChannelBuilder getChannel(final String host, final int port,
final File trustAnchorsFile) throws Exception{
String configName = "pkcs11.cfg"; // FIXME
SunPKCS11 sunpkcs11 = new SunPKCS11(configName);
Security.addProvider(sunpkcs11);
KeyStore.Builder scBuilder = KeyStore.Builder.newInstance("PKCS11", sunpkcs11,
new KeyStore.PasswordProtection("11111111".toCharArray())); //FIXME
KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509");
KeyStoreBuilderParameters param = new KeyStoreBuilderParameters(scBuilder);
factory.init(param);
SslContextBuilder builder = GrpcSslContexts.forClient();
builder = builder.trustManager(trustAnchorsFile)
.keyManager(factory)
.clientAuth(ClientAuth.REQUIRE);
return NettyChannelBuilder.forAddress(host, port).sslContext(builder.build());
}
тестируя этот код, я вижу, что он аутентифицируется на смарт-карте (предоставляя некоторый неправильный PIN-код (вместо "11111111"), уменьшает соответствующий счетчик повторов на карте. Кроме того, при использовании отладочной версии dll pkcs11, используемой Я вижу, что поставщик sun pkcs11 проверяет подлинность поставщика sun, перечисляет все ключи, читает все сертификаты и так (довольно часто), но не пытается выполнить какую-либо операцию с закрытым ключом. Кроме того, предоставляя -Djava.security.debug=sunpkcs11 JVM не дает больше внутри (я наткнулся на то, что при аутентификации клиента SSL с помощью смарт-карты работает в Java 6, но не работает в Java 7).
Используя wireshark, чтобы посмотреть на рукопожатие протокола TLS, похоже, клиент пытается пропустить часть аутентификации клиента, которая заставляет сервер закрывать соединение. Это приводит к некоторому исключению на клиенте:
io.grpc.StatusRuntimeException: UNAVAILABLE: канал закрыт при выполнении согласования протокола на io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:227) на io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.javao20).grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:141)
предоставление того же ключа и сертификатов со смарт-карты, что и файлы PEM, SslContextBuilder
приводит к работающему соединению, поэтому я заключаю, что сертификат (ы) и сам ключ не создают проблемы, но, возможно, / возможно, некоторая конфигурация sunpkcs11?
Кому-нибудь удалось использовать gRPC со смарт-картами PKCS#15 / токенами PKCS#11? У кого-нибудь есть дальнейшие предложения, как легко понять, что здесь не получается?