Scala 与 Akka 中的相互身份验证

2024-02-01

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


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

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

您需要做的总结是:

  • 对于客户

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

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

我不太清楚你使用的是什么类型的服务器,但如果你使用 spring-boot ,示例配置将是:

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 选项创建客户端的示例。

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。

  • Apache SSLContextBuilder https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/ssl/SSLContextBuilder.html
  • Jetty SslContextFactory https://www.eclipse.org/jetty/javadoc/9.4.14.v20181114/org/eclipse/jetty/util/ssl/SslContextFactory.html
  • SSLContext-Kickstart https://github.com/Hakky54/sslcontext-kickstart

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

下面概述了加载密钥库和创建​​ SSLContext 的四种方法。 Vanilla Java 并使用这三个库。

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的翻译功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 与 Akka 中的相互身份验证 的相关文章

随机推荐

  • Tomcat v7.0 Server 中的 Apache Axis2 Web 服务运行时不支持服务项目 Test

    Tomcat v7 0 Server 中的 Apache Axis2 Web 服务运行时不支持服务项目 Test 为什么 请帮我 我刚刚遇到了同样的问题 事实证明 Axis2不喜欢Eclipse的3 0动态Web项目 只需创建一个新的动态W
  • 在Python中将一个类的方法安全地绑定到另一个类[重复]

    这个问题在这里已经有答案了 我知道我可以将一个函数附加到一个类并使其成为一个方法 gt gt gt def is not bound inst name print Hello s name gt gt gt gt gt gt class
  • 停止调用 JNI 函数的 Java 线程

    在这里我想停止我的线程或杀死我的线程它是在Java层创建的 该线程正在调用JNI函数 有时根据我的应用程序要求 我必须停止此操作JNI函数执行在某些条件下 如果它正在进行 否则不会 new Thread new Runnable Overr
  • 如何管理具有不同数据库模式的git分支?

    我有一个项目 需要开发一项新功能 该功能需要重新设计部分数据库 同时保持主要开发分支在旧模式上工作 您管理此类项目的最佳实践是什么 我考虑过在开发新功能时拥有一个单独的数据库 但意识到这需要将数据库配置签入存储库 这是不行的 我还有其他方法
  • Angular2 与 Material Design Lite

    我在我的 angular2 应用程序中添加了以下代码 以帮助 MDL 在应用程序中移动时重新注册组件 ngAfterViewInit componentHandler upgradeDom 尽管它似乎工作正常 如预期 但我收到以下错误 16
  • 什么可以解释调用 free() 时的堆损坏?

    我已经调试了几天的崩溃 该崩溃发生在 OpenSSL 的深处 与维护者讨论here https www mail archive com openssl dev openssl org msg38571 html 我花了一些时间进行调查 所
  • 基本数据类型(字符串和整数)如何在 Python 和 Perl 中实现

    最近我一直想知道我对字符串和整数等基本类型执行的各种操作在性能方面如何工作 并且我认为如果我知道这些基本类型是如何实现的 即我已经听说 Python 中字符串和整数是不可变的 这是否意味着任何修改字符串中一个字符的操作都是 O n 因为必须
  • sql中的特殊字符排序

    我有名为 联系人 的表 有名为 id 和 name 的列 各列值如下所示 ID Name 1 ABC 3 DEF 2 GHI JKL null MNO null PQR 我需要查询要在顶行列出的特殊字符 如下所示 ID Name JKL 1
  • CakePHP:Ajax 请求的控制器响应错误

    我正在使用 jQuery 向某些控制器操作发出 AJAX 请求 该请求是通过同一控制器中编辑操作视图中的按钮激活的 我的问题 Ajax 请求返回编辑视图的所有代码 包含所有表单和输入 而不是预期的数量 如果我将相同的 ajax 按钮放在添加
  • javascript 在 Rails 3.1 基于资产的应用程序中包含两次

    尽管问题的标题与之前的一些问题非常相似 但我的问题似乎有所不同 简要地 第一项在 js 清单中包含两次 这是我的全部 app assets javascript application jsRails 3 1 应用程序中的文件 requir
  • iOS:UIPageViewController - 使用按钮跳转到下一页

    我在 PageViewController 中有一系列 VC 用户可以用手指从左到右导航 我需要添加按钮 这些按钮基本上执行与手指滑动相同的操作 即通过 VC 向左或向右移动 1 个 我怎样才能做到这一点 现在我正在使用这两种方法在用户滑动
  • Python pip freeze 中的三等号和 ubuntu2 是什么?

    在我的 AWS Ubuntu 14 04 实例上 我刚刚做了一个pip freeze gt requirements txt这给了我一个文件 其中还包含以下两行 python apt 0 9 3 5ubuntu2 python debian
  • PyCharm 中所有 pip 安装均“未找到匹配的发行版”

    我在 Windows 7 上运行 PyCharm Community Edition 2016 1 2 和 Python 3 4 3 并且有以下行为 在 PyCharm 中安装新包 从 设置 gt 项目解释器 失败并显示错误消息No mat
  • select from ... - 基于 JSON 格式的值

    假设我有一个数据库表 其中包含几个常见列 例如姓名 性别 年龄 此外 我还有一个附加列 使用 JSON 数据类型 可从 Postgres 9 2 获得 在 JSON 中具有任意长度和任意字段 occupation football occu
  • 当我在 youtube api 中使用 order-date 时,会出现总结果,但找不到项目

    当我在 youtube api 中使用 order date 时 会有总结果 但未找到项目 YOUR API KEY YOUR API KEY 这两个链接给出不同的结果 None
  • 通过另一个列表/数组过滤 Linq 子集合

    当我尝试根据简单值过滤子集合时 我可以通过执行以下操作轻松完成 db Table Where a gt a SubTable Any b gt b SubTableId 1 但是 当我尝试根据与其对应的值列表过滤同一个子集合时 我总是收到错
  • 我正在尝试在 angular1 项目中使用 ag-grid

    我在 Jhipster 从 Angular 1 项目开始 我对 ag grid 组件有一些问题 第一 我对所有组件使用 Bower 并在 angular js 文件之前包含我的 ag grid 文件 我想我可以通过使用覆盖来解决这个问题 但
  • 无法在 savon 调用上设置 SOAP 标头参数

    我正在使用 savon 2 2 进行 SOAP 调用 初始化 client Savon client wsdl SOAP WSDL endpoint SOAP URL 我可以像这样进行 SOAP 调用 并且效果很好 resp client
  • onBackPressed() 已弃用。还有什么选择呢?

    我已经升级了targetSdkVersion and compileSdkVersion to 33 我现在收到一条警告 告诉我按下后退 https developer android com reference android app A
  • Scala 与 Akka 中的相互身份验证

    我将使用 Akka 在 Scala 中创建一个 TLS 会话 并在客户端和服务器之间进行相互身份验证 我创建了两个 CA 证书 它们必须信任来自另一部分的相应证书 您能给我一个如何实现这一点的例子吗 谢谢 我创建了一个 github 项目