Secure Your gRPC Services With SSL/TLS
Learn how to easily set up TLS for your gRPC client and server application.
Join the DZone community and get the full member experience.
Join For FreeIntroduction
This tutorial will walk you through the process of protecting your gRPC services with encryption based on SSL/TLS. The tutorial will provide examples written in Java, but can easily be converted to Scala and Kotlin.
What is gRPC?
gRPC is a high-performance, open source RPC framework initially developed by Google. It helps in eliminating boilerplate code and helps in connecting polyglot services in and across data centers.
See here for more: https://grpc.io/
Maven Dependencies
The following maven dependencies will be used for the examples:
xxxxxxxxxx
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>sslcontext-kickstart-for-netty</artifactId>
</dependency>
Example SSL Configuration
Server
xxxxxxxxxx
import io.grpc.Server;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyServerBuilder;
import io.netty.handler.ssl.SslContext;
import nl.altindag.grpc.server.service.HelloServiceImpl;
import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.util.NettySslUtils;
import java.io.IOException;
public class App {
private Server server;
private void start() throws IOException {
SSLFactory sslFactory = SSLFactory.builder()
.withIdentityMaterial("server/identity.jks", "secret".toCharArray())
.withTrustMaterial("server/truststore.jks", "secret".toCharArray())
.withNeedClientAuthentication()
.build();
SslContext sslContext = GrpcSslContexts.configure(NettySslUtils.forServer(sslFactory)).build();
server = NettyServerBuilder.forPort(8443)
.addService(new HelloServiceImpl())
.sslContext(sslContext)
.build()
.start();
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final App server = new App();
server.start();
server.blockUntilShutdown();
}
}
Client
xxxxxxxxxx
package nl.altindag.grpc.client;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.netty.handler.ssl.SslContext;
import nl.altindag.grpc.HelloRequest;
import nl.altindag.grpc.HelloResponse;
import nl.altindag.grpc.HelloServiceGrpc;
import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.util.NettySslUtils;
import javax.net.ssl.SSLException;
public class App {
private final HelloServiceGrpc.HelloServiceBlockingStub stub;
public App(Channel channel) {
stub = HelloServiceGrpc.newBlockingStub(channel);
}
public void hello(String name) {
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloResponse response = stub.hello(request);
System.out.println(response.getMessage());
}
public static void main(String[] args) throws SSLException {
SSLFactory sslFactory = SSLFactory.builder()
.withIdentityMaterial("client/identity.jks", "secret".toCharArray())
.withTrustMaterial("client/truststore.jks", "secret".toCharArray())
.withDefaultTrustMaterial()
.build();
SslContext sslContext = GrpcSslContexts.configure(NettySslUtils.forClient(sslFactory)).build();
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 8443)
.sslContext(sslContext)
.build();
App app = new App(channel);
app.hello("John");
channel.shutdown();
}
}
Conclusion
In this tutorial, we saw how we could set up and configure SSL/TLS for gRPC on a client as well as server-side.
As usual, you'll find the sources over on GitHub.
Published at DZone with permission of Hakan Altındağ. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments