使用自签名证书的 Spray https 服务器的配置问题?

2023-12-26

我在 Mac 10.9.4 上使用 Spray 1.3、Akka 2.3 和 Scala 2.11 来设置 HTTP 服务器。我正在关注 Ch. Manning 的 Akka in Action 中的 2 个示例(此处提供示例代码:https://github.com/RayRoestenburg/akka-in-action.git https://github.com/RayRoestenburg/akka-in-action.git),当我使用 http 时,它会按预期编译、运行和运行,但我在配置它以与 https 一起使用时遇到问题。

为了使用 https 运行,我生成了一个自签名证书,如下所示:

keytool -genkey -keyalg RSA -alias selfsigned -keystore myjks.jks -storepass abcdef -validity 360 -keysize 2048

按照这个例子,https://github.com/spray/spray/tree/v1.2-M8/examples/spray-can/simple-http-server/src/main/scala/spray/examples https://github.com/spray/spray/tree/v1.2-M8/examples/spray-can/simple-http-server/src/main/scala/spray/examples

我添加了一个 SSL 配置类:

package com.goticks

import java.security.{SecureRandom, KeyStore}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}
import spray.io._

// for SSL support (if enabled in application.conf)
trait MySSLConfig {

  // if there is no SSLContext in scope implicitly the HttpServer uses the default SSLContext,
  // since we want non-default settings in this example we make a custom SSLContext available here
  implicit def sslContext: SSLContext = { 
    val keyStoreResource = "myjks.jks"
    val password = "abcdef"

    val keyStore = KeyStore.getInstance("jks")
    keyStore.load(getClass.getResourceAsStream(keyStoreResource), password.toCharArray)
    val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
    keyManagerFactory.init(keyStore, password.toCharArray)
    val trustManagerFactory = TrustManagerFactory.getInstance("SunX509")
    trustManagerFactory.init(keyStore)
    val context = SSLContext.getInstance("TLS")
    context.init(keyManagerFactory.getKeyManagers, trustManagerFactory.getTrustManagers, new SecureRandom)
    context
  }

  // if there is no ServerSSLEngineProvider in scope implicitly the HttpServer uses the default one,
  // since we want to explicitly enable cipher suites and protocols we make a custom ServerSSLEngineProvider
  // available here
  implicit def sslEngineProvider: ServerSSLEngineProvider = { 
    ServerSSLEngineProvider { engine =>
      engine.setEnabledCipherSuites(Array("TLS_RSA_WITH_AES_256_CBC_SHA"))
      engine.setEnabledProtocols(Array("SSLv3", "TLSv1"))
      engine
    }   
  }
}

我已更新 Main 类以使用 SSL 配置:

package com.goticks

import akka.actor._
import akka.io.IO

import spray.can.Http
import spray.can.server._

import com.typesafe.config.ConfigFactory

object Main extends App with MySSLConfig {
  val config = ConfigFactory.load()
  val host = config.getString("http.host")
  val port = config.getInt("http.port")

  implicit val system = ActorSystem("goticks")

  val api = system.actorOf(Props(new RestInterface()), "httpInterface")
  IO(Http) ! Http.Bind(listener = api, interface = host, port = port)
}

我已经更新了 application.conf:

spray {
  can {
    server {
      server-header = "GoTicks.com REST API"
      ssl-encryption = on
    }
  }
}

编译并运行服务器后,当我尝试执行 https GET 时,出现以下错误:

[ERROR] [09/15/2014 10:40:48.056] [goticks-akka.actor.default-dispatcher-4] [akka://goticks/user/IO-HTTP/listener-0/7] Aborting encrypted connection to localhost/0:0:0:0:0:0:0:1%0:59617 due to [SSLHandshakeException:no cipher suites in common] -> [SSLHandshakeException:no cipher suites in common]

我不确定我的问题是与生成的密钥有关,还是与我的配置有关。顺便说一句,我的最终目标是将此配置与 TCP 套接字一起使用(请参阅我的其他问题:Scala 上的 TCP 套接字和 Akka 上的 SSL https://stackoverflow.com/questions/25797965/tcp-socket-with-ssl-on-scala-with-akka),但我无法找到运行安全 TCP 的文档,所以我想我应该从 HTTPS 开始。

任何帮助表示赞赏。


我终于能够使用它来工作阿帕奇骆驼 http://camel.apache.org/按照发现的建议here https://groups.google.com/d/msg/spray-user/Vtgtaf_duB8/ke5s1yRik7oJ。仅仅为了设置 SSLContext 就引入 Camel 似乎有点矫枉过正,但这就是最终起作用的方法。

我的 SSLConfig 最终看起来像这样:

import javax.net.ssl.SSLContext
import spray.io._
import org.apache.camel.util.jsse._

trait MySSLConfig {
    implicit def sslContext: SSLContext = {
        //val keyStoreFile = "/Users/eschow/repo/services/jks/keystore.jks"
        val keyStoreFile = "/Users/eschow/code/scala/akka-in-action/chapter2/myjks.jks"

        val ksp = new KeyStoreParameters()
        ksp.setResource(keyStoreFile);
        ksp.setPassword("abcdef")

        val kmp = new KeyManagersParameters()
        kmp.setKeyStore(ksp)
        kmp.setKeyPassword("abcdef")

        val scp = new SSLContextParameters()
        scp.setKeyManagers(kmp)

        val context= scp.createSSLContext()

        context
      }

    implicit def sslEngineProvider: ServerSSLEngineProvider = {
        ServerSSLEngineProvider { engine =>
            engine.setEnabledCipherSuites(Array("TLS_RSA_WITH_AES_256_CBC_SHA"))
            engine.setEnabledProtocols(Array("SSLv3", "TLSv1"))
            engine
        }
    }
}

顺便说一句,Camel 记录的错误更有帮助。做一些愚蠢的事情,例如提供通往梯形校正的错误路径或不正确的密码,会产生有意义的、人类可读的错误,而不是我之前看到的无声故障。

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

使用自签名证书的 Spray https 服务器的配置问题? 的相关文章

  • Spark scala:大量列上的简单 UDF 会导致性能下降

    我有一个包含 1 亿行和约 10 000 列的数据框 这些列有两种类型 标准 C i 和动态 X i 这个dataframe是经过一些处理后得到的 性能很快 现在只剩下2步了 Goal 需要使用 C i 列的相同子集对每个 X i 执行特定
  • Slick 中的 Scala 枚举(案例对象),良好实践

    假设我有一个代表一组几个有效状态的特征 将对象存储在数据库中是一个好习惯吗 存储 Int 并使用隐式函数 MappedColumnType base Int DoorState 将它们映射到 DoorState 会更好吗 trait Doo
  • 一般处理枚举的 Scala 类

    我想创建一个通用类来保存枚举的值 并且还允许访问枚举的可能值 以属性编辑器为例 您需要知道属性的当前值 并且还需要能够知道该属性的其他合法值 并且枚举的类型不应该提前知道 您应该能够使用任何类型的枚举 我的第一个想法是这样的 class E
  • 标识符中下划线的 Scala 风格指南

    我已经接受了许多其他语言的观点 即下划线在标识符中具有与字母表一样多的自由度 因此 v and v 另外 尾随下划线是受到推崇的避免与保留关键字产生歧义 class case val abc 0
  • 这种奇怪的 Scala 内存泄漏的原因是什么? [复制]

    这个问题在这里已经有答案了 即使有 7G 的堆空间 这也会耗尽内存 import scala collection mutable Set class Foo val anEmptySet Set Int Set def bar ints
  • Scala案例类使用浅拷贝还是深拷贝?

    case class Person var firstname String lastname String val p1 Person amit shah val p2 p1 copy p1 firstname raghu p1 p2 p
  • Spark DataFrame 不尊重架构并将所有内容视为字符串

    我面临着一个多年来一直无法克服的问题 我使用的是 Spark 1 4 和 Scala 2 10 我现在无法升级 大型分布式基础设施 我有一个包含几百列的文件 其中只有 2 列是字符串 其余都是长列 我想将此数据转换为标签 特征数据框 我已经
  • Scala 中的模式匹配是如何在字节码级别实现的?

    Scala 中的模式匹配是如何在字节码级别实现的 是不是像一系列if x instanceof Foo 构造 还是其他什么 它对性能有何影响 例如 给出以下代码 来自Scala 示例 http www scala lang org docu
  • 将括号子集映射到字符

    我正在尝试创建一个 Scala 方法 该方法将采用一个父括号组 表示为字符串 然后将每个括号子组映射到不同的字母 然后它应该将它们放入它返回的映射中 所以基本上我调用以下方法 如下所示 val s 2 x 3 6 val map mapPa
  • 视图和流有什么区别?

    在Scala 2 8集合框架中 有什么区别view and toStream 在视图中 每次访问元素时都会重新计算它们 在流中 元素在求值时会被保留 例如 val doubled List 1 2 3 4 5 6 7 8 9 10 view
  • 如何对 RDD 进行分区

    我有一个文本文件 其中包含大量由空格分隔的随机浮动值 我正在将此文件加载到 scala 中的 RDD 中 这个RDD是如何分区的 另外 是否有任何方法可以生成自定义分区 以便所有分区都具有相同数量的元素以及每个分区的索引 val dRDD
  • 在 scalaz 中免费实施

    Haskell 中的免费实现是 data Free f a Pure a Free f Free f a 而 Scalaz 中的实现是 sealed abstract class Free S A private case class Re
  • Scala 中 Null/Nothing/Unit 的用法

    我刚刚读过 http oldfashionedsoftware com 2008 08 20 a post about nothing http oldfashionedsoftware com 2008 08 20 a post abou
  • Scala 宏 - 使用“c.prefix”推断隐式值

    c inferImplicitValue推断调用站点范围中的隐式值 是否可以使用推断隐式c prefix scope 这不是有效的代码 但表达了我需要的内容 c prefix inferImplicitValue 我目前正在使用一个简单的实
  • 在 Scala 中使用隐式的良好实践 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何客观原因在代码中到处使用隐式参数只是为了缩短应传递的参数数量 我有一个 REST API 端点的每个调用都有一个唯一的 ID 应该在调
  • Scalaz 状态 monad 示例

    我还没有看到很多 scalaz 状态单子的例子 有这个例子 http scalaz github com scalaz scalaz 2 9 1 6 0 2 doc sxr scalaz example ExampleState scala
  • Scala Continuations - 为什么我的转移调用不能位于 try-catch 块内?

    我对 Scala 延续很陌生 而且对一般的 scala 语言也比较陌生 我尝试使用 Scala 延续并编写了以下代码 case class MyException msg String extends Exception def go In
  • Scala 模式与 TypeTag 的泛型匹配会生成警告,而 ClassTag 不会?

    我有两种非常相似的方法 唯一的区别是使用ClassTag and TypeTag def matchClass A ClassTag v Any v match case a A gt it s A case gt not A def ma
  • 乔达时间:将 UTC 转换为本地时间

    我想将 Joda Time UTC DateTime 对象转换为本地时间 这是一种看似有效的费力方法 但一定有更好的方法 这是没有周围声明的代码 在 Scala 中 val dtUTC new DateTime 2010 10 28T04
  • Scala Stream 按需要调用(惰性)与按名称调用

    所以我知道按需要呼叫只是按名称呼叫的记忆版本 在 Martin Odersky 在 Coursera 上的 FP 课程中 第 7 3 讲 惰性评估 中 他提到如果 Streams 是使用按名称调用来实现的 那么它可能会导致计算复杂性的激增

随机推荐