gpt4 book ai didi

postgresql - Scala:如何建立与 PostgreSQL 服务器的安全连接?

转载 作者:太空宇宙 更新时间:2023-11-03 13:54:52 25 4
gpt4 key购买 nike

我想以编程方式安全地连接到我的 PostgreSQL 服务器Scala 使用基于 JDBC 的库。此外,我想存储所有openssl 生成格式的 SSL 证书和 key 文件(不是原生Java生成的KeyStore格式库)。

我该怎么做?

我正在使用:

  • PostgreSQL 9.3
  • JVM 1.6
  • Scala 2.10.3

最佳答案

扩展 org.postgresql.ssl.WrappedFactory属于的类 PostgreSQL JDBC Driver ,然后通过扩展类的名称作为 setSslfactory() 方法的参数BaseDataSource 的适当子类.

例子

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

假设 PostgreSQL login role你会用它来建立连接名为 database_user:

使用 PostgreSQL 服务器的证书签署客户端证书具有通用名称 (CN) 属性 database_user。然后,使用服务器的证书、客户端的证书和客户端机器上的 openssl PEM 格式的客户端私钥,以下将启用安全的、双边认证的连接到 PostgreSQL 服务器:

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 DataSource像这样:

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
}

注意事项:

  1. 这段代码没有捕获异常,也没有关闭 Streams/Readers。根据需要修改。
  2. 此代码不针对服务器验证客户端证书证书,也不是针对客户端证书的私钥(超出连接尝试)。提防相关错误,并根据需要进行修改。
  3. 底层 Java 方法通常接受 null 作为有意义的争论。如果您注意到奇怪的行为,请确保您没有不小心在某处传递了一个 null 方法参数。
  4. 上述使用 RSA key 对。较新的版本openssl可以使用椭圆曲线加密。
  5. 实现 forward secrecy ,考虑在 PostgreSQL 中指定适当的密码套件配置,例如:

    ssl_ciphers = '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"
)

你的 pg_hba.conf文件将需要一个适当的条目,例如:

hostssl my_database database_user <client.ip.number>/32 trust clientcert=1

关于postgresql - Scala:如何建立与 PostgreSQL 服务器的安全连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20826381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com