Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:如何建立到PostgreSQL server的安全连接?_Postgresql_Scala_Ssl - Fatal编程技术网

Scala:如何建立到PostgreSQL server的安全连接?

Scala:如何建立到PostgreSQL server的安全连接?,postgresql,scala,ssl,Postgresql,Scala,Ssl,我希望以编程方式在中安全地连接到PostgreSQL server Scala使用基于JDBC的库。此外,我想储存所有的 采用openssl生成的格式的SSL证书和密钥文件 (即,非本机Java生成的密钥库格式 图书馆) 我该怎么做 我正在使用: PostgreSQL 9.3 JVM1.6 Scala 2.10.3 扩展 类的一部分 ,然后通过 作为setSslfactory()方法参数的扩展类的名称 属于……的一个适当的子类 例子 假设您使用自签名证书作为PostgreSQL 服务器的证书(

我希望以编程方式在中安全地连接到PostgreSQL server Scala使用基于JDBC的库。此外,我想储存所有的 采用
openssl生成的格式的SSL证书和密钥文件
(即,本机Java生成的
密钥库
格式 图书馆)

我该怎么做

我正在使用:

  • PostgreSQL 9.3
  • JVM1.6
  • Scala 2.10.3
扩展 类的一部分 ,然后通过 作为
setSslfactory()
方法参数的扩展类的名称 属于……的一个适当的子类

例子 假设您使用自签名证书作为PostgreSQL 服务器的证书(注意,服务器的证书在文件中 其名称被指定为配置参数的值 ),及

假设您将使用PostgreSQL建立 连接名为数据库用户

使用PostgreSQL server的证书对客户端证书进行签名 具有公共名称(
CN
)属性的
数据库\用户
。 然后,使用服务器证书、客户端证书和 客户端计算机上的每个客户端私钥均为
openssl
PEM格式, 以下内容将启用安全的双边身份验证连接 到PostgreSQL server:

package mypackage

import org.postgresql.ssl.WrappedFactory

import org.bouncycastle.util.io.pem.PemReader

import java.io.{FileInputStream,FileReader}
import javax.net.ssl.{SSLContext,KeyManagerFactory,TrustManagerFactory}
import java.security.{KeyStore,KeyFactory,SecureRandom}
import java.security.cert.CertificateFactory
import java.security.spec.PKCS8EncodedKeySpec

object SocketFactory {
  final val PRIVATE_KEY_FILENAME = "private.key"
  final val CLIENT_CERT_FILENAME = "client.crt"
  final val SERVER_CERT_FILENAME = "/home/me/.ssl/postgres_server.crt"

  def certFromFile(fileName: String) =
    CertificateFactory getInstance "X.509" generateCertificate {
      new FileInputStream(fileName)
    }
}

class SocketFactory extends WrappedFactory {
  import SocketFactory._

  val sslContext = SSLContext getInstance "TLS"

  sslContext init (
    { // key managers: Array[KeyManager] 
      val kmf = KeyManagerFactory getInstance "SunX509"
      kmf init ({
        val keyStore = KeyStore getInstance KeyStore.getDefaultType
        keyStore load (null, null)
        keyStore setKeyEntry ( "",
          KeyFactory getInstance "RSA" generatePrivate (
            new PKCS8EncodedKeySpec (
              new PemReader (
                new FileReader(PRIVATE_KEY_FILENAME)
              ).readPemObject.getContent
            )
          ),
          Array[Char](), // no password for this entry
          Array(certFromFile(CLIENT_CERT_FILENAME))
        )
        keyStore
      }, Array[Char]())
      kmf.getKeyManagers
    },
    { // trust managers: Array[TrustManager]
      val tmf = TrustManagerFactory getInstance "PKIX"
      tmf init {
        val keyStore = KeyStore getInstance KeyStore.getDefaultType
        keyStore load (null, null)
        keyStore setCertificateEntry ("", certFromFile(SERVER_CERT_FILENAME))
        keyStore
      }            
      tmf.getTrustManagers
    },
    SecureRandom getInstance "SHA1PRNG"
  )

  _factory = sslContext.getSocketFactory

}
使用上述方法,您可以得到一个Java 大概是这样的:

def dataSource = {
  val ds = new PGSimpleDataSource
  ds.setDatabaseName("my_database")
  ds.setServerName("myHost.com")
  ds.setUser("database_user")
  ds.setSsl(true)
  ds.setSslfactory("mypackage.SocketFactory")
  ds
}
笔记:
  • 此代码不捕获任何异常,也不关闭流/读取器。根据需要修改
  • 此代码不会针对服务器验证客户端证书 证书,也不是针对客户端证书的私钥 (连接尝试之外)。提防 相关错误,并根据需要进行修改
  • 底层Java方法通常接受有意义的
    null
    论据。如果你注意到奇怪的行为,莫克确定你没有 意外地将
    null
    方法参数传递到某处
  • 前面使用的是RSA密钥对。最新版本的
    openssl
    可以使用椭圆曲线加密
  • 达到 , 考虑在PostgreSQL中指定适当的密码套件 配置,例如:

    ssl\u密码='DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA'

  • 其他文件 前面的示例在
    build.sbt
    文件:

    libraryDependencies ++= Seq(
      "org.bouncycastle"   % "bcpkix-jdk15on" % "1.50",
      "org.postgresql"     % "postgresql"   % "9.3-1100-jdbc4"
    )
    
    你的 文件将需要一个适当的条目,例如:

    hostssl my_database database_user <client.ip.number>/32 trust clientcert=1
    
    hostssl我的数据库用户/32信任客户端证书=1