如何读取与 OpenSAML 一起使用的私钥?
好吧,这是另一个“我不知道从哪里开始”的问题,所以希望答案很简单。然而,我真的不知道要搜索什么,而且到目前为止我的尝试并没有多大用处。
我想从(当前在磁盘上)文件中读取私钥。最终密钥将驻留在数据库中,但这对于目前来说已经足够了,并且这种差异应该对解析密钥材料没有真正的影响。我已经能够创建一个 Credential 实例来保存密钥的公共部分(由调试器确认),但我似乎不知道如何读取私有部分。密钥对生成为:(
openssl genrsa 512 > d:\host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key d:\host.key > d:\host.cert
是,我知道 512 位 RSA 密钥很久以前就被破解了。但是,为了尝试让 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
的私钥部分,以便我可以使用生成的 用于签署数据的凭证
实例?
OK, this is another of those "I have no real idea where to start" questions, so hopefully the answer is simple. However, I don't really know what to search for, and my attempts so far haven't turned up much of use.
I want to read a private key from a (currently on-disk) file. Ultimately the key will reside in a database, but this will be good enough for the moment and that difference should have no real bearing on parsing the key material. I have been able to create a Credential
instance that holds the public part of the key (confirmed by debugger), but I can't seem to figure out how to read the private part. The key pair was generated as:
openssl genrsa 512 > d:\host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key d:\host.key > d:\host.cert
(Yes, I know that 512 bit RSA keys were broken long ago. However, for trying to get the API to work, I see no reason to exhaust the system entropy supply needlessly.)
The code thus far is:
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;
}
But how do I read the file host.key
into the private key portion of credential
, so I can use the generated Credential
instance to sign data?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
BasicX509Credential
不是标准 Java 的一部分;我想您正在谈论来自 OpenSAML 的org.opensaml.xml.security.x509.BasicX509Credential
。您需要一个
PrivateKey
,您将使用credential.setPrivateKey()
设置它。要获得PrivateKey
,您必须首先将私钥转换为 Java 可以读取的格式,即 PKCS#8:然后,来自 Java:
瞧!您有您的
PrivateKey
。默认情况下,openssl 以自己的格式写入密钥(对于 RSA 密钥,PKCS#8 恰好是该格式的包装器),并且它以 PEM 对其进行编码,这带有页眉和页脚的 Base64。普通 Java 不支持这两个特性,因此转换为 PKCS#8。
-nocrypt
选项是因为 PKCS#8 支持可选的基于密码的私钥加密。警告:您确实确实想要使用更长的 RSA 密钥。 512 位较弱; 1999 年,数百台计算机上的 512 位 RSA 密钥被破解。 2011 年,随着 12 年的技术进步,人们应该假设 512 位 RSA 密钥几乎可以被任何人破解。因此,至少使用 1024 位 RSA 密钥(最好是 2048 位;使用密钥时的计算开销并没有那么糟糕,您仍然能够每秒执行数百个签名)。
BasicX509Credential
is not part from standard Java; I suppose you are talking aboutorg.opensaml.xml.security.x509.BasicX509Credential
from OpenSAML.You want a
PrivateKey
which you will set withcredential.setPrivateKey()
. To get aPrivateKey
, you must first convert the private key into a format that Java can read, namely PKCS#8:Then, from Java:
and voilà! you have your
PrivateKey
.By default,
openssl
writes key in its own format (for RSA keys, PKCS#8 happens to be a wrapper around that format), and it encodes them in PEM, which Base64 with a header and a footer. Both characteristics are unsupported by plain Java, hence the conversion to PKCS#8. The-nocrypt
option is because PKCS#8 supports optional password-based encryption of private key.Warning: you really really want to use a longer RSA key. 512 bits are weak; a 512-bit RSA key was broken in 1999 with a few hundred computers. In 2011, with 12 years of technological advances, one should assume that a 512-bit RSA key can be broken by almost anybody. Therefore, use 1024-bit RSA keys at least (preferably, 2048-bit; the computational overhead when using the key is not that bad, you will still be able to perform hundred of signatures per second).
这个问题与 SAML 相关,也与想要检索用于签署 XMLObject 的私钥的人相关。上面的答案效果很好,也可以从密钥库检索私钥:
这比原始查询请求的代码更多,但看起来他们正在尝试获取 BasicX509Credential。
谢谢,
约格什
This question is related to SAML and is also relevant for someone who wants to retrieve a private key for signing an XMLObject. The answer above works great and it also possible to retrieve a private key from a keystore as well:
This is more code than the original query requested, but it looks they are trying to get at a BasicX509Credential.
Thanks,
Yogesh