在 Scala 中使用 Akka 进行相互认证 [英] Mutual Authentication in Scala with Akka

查看:48
本文介绍了在 Scala 中使用 Akka 进行相互认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将使用 Akka 在 Scala 中创建一个 TLS 会话,并在客户端和服务器之间进行相互身份验证.我创建了两个 CA 证书,它们必须信任从另一部分传入的相应证书.你能给我一个如何实施的例子吗?谢谢.

I would create a TLS Session in Scala using Akka with mutual authentication between a client and a server. I have created two CA certificate that have to trust the respective certificates incoming from the other part. Could you give me an exemple of how implement this? Thank you.

推荐答案

我创建了一个 github 项目,该项目演示了与不同类型客户端(包括 Akka)的相互身份验证.请看这里:https://github.com/Hakky54/mutual-tls-ssl

I created a github project which demonstrates mutual authentication with different kind of clients, including Akka. Please have a look here: https://github.com/Hakky54/mutual-tls-ssl

它包含了将 ssl 材料加载到客户端和服务器的完整示例

It contains a full example of loading the ssl material into the client and server

总结一下你需要做的是:

A summary what you need to do is:

  • 为了客户

  • For the client

  • 创建密钥和证书并将其加载到密钥库中
  • 导出证书
  • 为可信证书创建单独的密钥库并导入服务器证书
  • 将两个密钥库加载到您的 http 客户端

对于服务器

  • 创建密钥和证书并将其加载到密钥库中
  • 导出证书
  • 为可信证书创建单独的密钥库并导入客户端证书
  • 将两个密钥库加载到您的服务器中

我不太清楚您使用的是哪种服务器,但如果您使用的是 spring-boot,示例配置将是:

It is not really clear to me what kind of server you are using, but if you are using spring-boot the example configuration would be:

server:
  port: 8443
  ssl:
    enabled: true
    key-store: classpath:identity.jks
    key-password: secret
    key-store-password: secret
    trust-store: classpath:truststore.jks
    trust-store-password: secret
    client-auth: need

Akka 需要预先配置的 SSLContext 实例才能配置 HTTPS.使用 https 选项创建客户端的示例是下面的代码片段.

Akka requires a pre-configured instance of SSLContext to be able to configure HTTPS. An example of creating a client with https options would be the code snippet below.

import akka.actor.ActorSystem;
import akka.http.javadsl.ConnectionContext;
import akka.http.javadsl.Http;
import akka.http.javadsl.HttpsConnectionContext;
import com.typesafe.config.ConfigFactory;

import javax.net.ssl.SSLContext;
import java.util.Optional;

class App {

    public static void main(String[] args) {
        ActorSystem actorSystem = ActorSystem.create(
                App.class.getSimpleName(),
                ConfigFactory.defaultApplication(App.class.getClassLoader())
        );

        SSLContext sslContext = ...; //Initialized SSLContext

        Http http = Http.get(actorSystem);
        HttpsConnectionContext httpsContext = ConnectionContext.https(
                sslContext,
                Optional.empty(),
                Optional.empty(),
                Optional.empty(),
                Optional.of(sslContext.getDefaultSSLParameters()));
        http.setDefaultClientHttpsContext(httpsContext);
    }
}

有几个库提供易于使用的实用程序/工厂/构建器类来帮助您创建 SSLContext.

There are couple of libraries which provides easy to use utility/factory/builder classes to help you to create a SSLContext.

可能有很多其他库提供类似的功能,但我只知道这三个.顺便说一句,sslcontext-kickstart 是一个由我维护的库.

There could be a bunch other libraries which provide similar functionality, but I am only aware of these three. By the way the sslcontext-kickstart is a library which is maintained by me.

以下是加载密钥库和创建​​ SSLContext 的四种方法的概述.Vanilla Java 并使用三个库.

Below is an overview of four ways to load the keystores and create an SSLContext. Vanilla Java and by using the three libraries.

import io.netty.handler.ssl.SslContextBuilder;
import nl.altindag.sslcontext.SSLFactory;
import org.apache.http.ssl.SSLContextBuilder;
import org.eclipse.jetty.util.ssl.SslContextFactory;

import javax.net.ssl.*;
import java.io.File;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Objects;

class SslExample {

    public static void main(String[] args) throws Exception {

        //Traditional flow of creating sslContext
        String keyStorePath = "keystore.p12";
        String trustStorePath = "truststore.p12";

        char[] keyStorePassword = "secret".toCharArray();
        char[] trustStorePassword = "secret".toCharArray();

        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        KeyStore trustStore = KeyStore.getInstance("PKCS12");

        try(InputStream keyStoreInputStream = SslExample.class.getClassLoader().getResourceAsStream(keyStorePath);
            InputStream trustStoreInputStream = SslExample.class.getClassLoader().getResourceAsStream(trustStorePath)) {

            Objects.requireNonNull(keyStoreInputStream);
            Objects.requireNonNull(trustStoreInputStream);

            keyStore.load(keyStoreInputStream, keyStorePassword);
            trustStore.load(trustStoreInputStream, trustStorePassword);
        }

        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, keyStorePassword);
        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(keyManagers, trustManagers, new SecureRandom());

        //creating sslContext with Apache SSLContextBuilder
        SSLContext sslContext1 = SSLContextBuilder.create()
                .loadKeyMaterial(new File("keystore.p12"), "secret".toCharArray(), "secret".toCharArray())
                .loadTrustMaterial(new File("truststore.p12"), "secret".toCharArray())
                .build();

        //creating sslContext with Jetty SslContextFactory
        SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
        sslContextFactory.setKeyStorePath("keystore.p12");
        sslContextFactory.setKeyStorePassword("secret");
        sslContextFactory.setTrustStorePath("truststore.p12");
        sslContextFactory.setTrustStorePassword("secret");
        sslContextFactory.start();

        SSLContext sslContext2 = sslContextFactory.getSslContext();

        //creating sslContext with sslcontext-kickstart
        SSLFactory sslFactory = SSLFactory.builder()
                .withIdentity("keystore.p12", "secret".toCharArray())
                .withTrustStore("truststore.p12", "secret".toCharArray())
                .build();

        SSLContext sslContext3 = sslFactory.getSslContext();
    }

}

它是在 Java 中,但 IntelliJ Idea 在粘贴代码片段时提供了一个方便的转换函数到 Scala.

It is in java, but IntelliJ Idea provides a handy translate function to scala when pasting the code snippet.

这篇关于在 Scala 中使用 Akka 进行相互认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆