java - 如何读取用于 OpenSAML 的私钥?

标签 java cryptography opensaml

好吧,这是另一个“我不知道从哪里开始”的问题,所以希望答案很简单。但是,我真的不知道要搜索什么,到目前为止我的尝试没有多大用处。

我想从一个(当前在磁盘上的)文件中读取私钥。最终 key 将驻留在数据库中,但目前这已经足够了,而且这种差异对解析 key Material 应该没有真正的影响。我已经能够创建一个 Credential 实例来保存 key 的公共(public)部分(由调试器确认),但我似乎无法弄清楚如何读取私有(private)部分。 key 对生成为:

openssl genrsa 512 > d:\host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key d:\host.key > d:\host.cert

(是的,我知道 512 位 RSA key 很久以前就被破解了。但是,为了让 API 正常工作,我认为没有理由不必要地耗尽系统熵供应。)

到目前为止的代码是:

import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.x509.BasicX509Credential;

private Credential getSigningCredential()
throws java.security.cert.CertificateException, IOException {
    BasicX509Credential credential = new BasicX509Credential();

    credential.setUsageType(UsageType.SIGNING);

    // read public key
    InputStream inStream = new FileInputStream("d:\\host.cert");
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
    inStream.close();
    credential.setEntityCertificate(cert);

    // TODO: read private key

    // done.
    return credential;
}

但是如何将文件 host.key 读入 credential 的私钥部分,以便我可以使用生成的 Credential 实例签署数据?

最佳答案

BasicX509Credential 不是标准 Java 的一部分;我想您是在谈论来自 OpenSAML 的 org.opensaml.xml.security.x509.BasicX509Credential

您需要一个 PrivateKey,您将使用 credential.setPrivateKey() 进行设置。要得到一个PrivateKey,首先要将私钥转换成Java可以读取的格式,即PKCS#8:

openssl pkcs8 -topk8 -nocrypt -outform DER < D:\host.key > D:\host.pk8

然后,从 Java:

RandomAccessFile raf = new RandomAccessFile("d:\\host.pk8", "r");
byte[] buf = new byte[(int)raf.length()];
raf.readFully(buf);
raf.close();
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(kspec);

瞧!你有你的 PrivateKey

默认情况下,openssl 以自己的格式写入 key (对于 RSA key ,PKCS#8 恰好是该格式的包装器), 并将它们编码为PEM,其中带有页眉和页脚的 Base64。纯 Java 不支持这两个特性,因此转换为 PKCS#8。 -nocrypt 选项是因为 PKCS#8 支持可选的基于密码的私钥加密。

警告:您真的真的想要使用更长的 RSA key 。 512位弱; 512 位 RSA key 在 1999 年被数百台计算机破解。在 2011 年,随着 12 年的技术进步,人们应该假设几乎任何人都可以破解 512 位 RSA key 。因此,至少使用 1024 位 RSA key (最好是 2048 位;使用 key 时的计算开销还不错,您仍然可以每秒执行数百个签名)。

关于java - 如何读取用于 OpenSAML 的私钥?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5230942/

相关文章:

java - HTTP URL token 标准

java - 使用相同的 key 在 C# 中加密并在 Java 中解密

opensaml - 如何使用 OpenSAML 设置 Signature DigestMethod 算法

java - 为了实现 SAML,我是否需要在我的主机上安装 Shibboleth SP?

java - 在可运行的jar中使用jogl,手动加载dll

java - 按住键后做某事并在释放和按下时重复

java.sql.SQLException : ResultSet closed on sqlite 异常

java - 如何在 Android MVVM 虚拟机中模拟父子关系?

c# - 如何使用 FromBase64String 创建长度为 16 的 byte[]

java - 为 SP 生成 OpenSaml 元数据