用Java签署X.509证书
我想了解如何签署x.509证书 我已经设置了一个OpenSSL CA来创建一个演示证书。证书很好,我可以使用名为dumpasn1的工具查看所有相关元素。 理论上,我知道我必须对名为“tbsCertificate”的结构进行签名,该结构包含属性版本、序列号签名、颁发者、有效性、主题、主题PublicKeyInfo和扩展 然而,当我试图在Java中模仿它时,不幸的是它不起作用。 我所做的是:用Java签署X.509证书,java,certificate,x509,signing,asn.1,Java,Certificate,X509,Signing,Asn.1,我想了解如何签署x.509证书 我已经设置了一个OpenSSL CA来创建一个演示证书。证书很好,我可以使用名为dumpasn1的工具查看所有相关元素。 理论上,我知道我必须对名为“tbsCertificate”的结构进行签名,该结构包含属性版本、序列号签名、颁发者、有效性、主题、主题PublicKeyInfo和扩展 然而,当我试图在Java中模仿它时,不幸的是它不起作用。 我所做的是: 我阅读了DER编码证书的“tbsCertificate”部分 然后我从颁发CA获得私钥 最后,我尝试使用以
- 我阅读了DER编码证书的“tbsCertificate”部分
- 然后我从颁发CA获得私钥
- 最后,我尝试使用以下代码对tbsCertificate结构进行签名:
public static X509Certificate loadCertificate(String fileName)
{
InputStream in;
byte [] signature;
X509Certificate cert = null;
try
{
in = new FileInputStream(fileName);
CertificateFactory factory = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) factory.generateCertificate(in);
signature = cert.getSignature();
System.out.println("Signature Algorithm: " + cert.getSigAlgName());
System.out.println(signature);
return cert;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (CertificateException e)
{
e.printStackTrace();
}
return cert;
}
ECDSA不会生成稳定的签名,因此,如果您的测试是生成相同的答案,那么该测试将不起作用。您可以通过根据tbsCertificate数据验证签名来验证证书上的签名 您的方法可以使用RSA签名,因为这是一种稳定的签名算法(使用PKCS1填充,而不是PSS) 至于找到tbsCertificate:您似乎确实知道DER编码是什么,但我觉得有必要根据问题中的松散描述提供指导: 证书的二进制编码形式为DER。第一个字节将是0x30((构造)序列)。下一个字节是序列的长度(<0x80)或长度(0x82=>下两个字节是大端长度)。下一个字节将再次为0x30,即tbsCertificate编码值的开始。然后可以读取该结构的长度,并计算tbsCertificate的正确端点偏移量
可以在中找到证书结构。(在中有一个更新,但我听到有人说“这没有作为标准获得批准”。)它也可以与属性证书一起在中使用——这就是X.509中的X.509证书的来源。我链接到2012版是因为2016版是在付费墙后面。谢谢你的回答。我知道DER编码,它是从一个序列开始的。我只是不想让这个问题变得更长更复杂。我也知道RFC3280,它或多或少是关于tbsCertificate清楚。如果我解释正确,它应该从第二个“序列”字节开始,偏移量为4,并一直延伸到给定的长度。你说ECDSA不能产生稳定的签名是什么意思?我想做的正是您所描述的——我想在tbsCertificate上运行签名算法,以便重新创建签名。我想我现在明白了稳定的含义——谢谢你对此事的评论。我原以为我可以重新制作签名。多亏了你的提示,我试着重新签署了考试证书,似乎效果不错。当我验证修补后的证书时,它会验证ok。很高兴我能提供帮助:)。在“谢谢”上写上:如果答案是正确的,请标记为正确。如果有帮助,你也可以选择向上投票。
public static X509Certificate loadCertificate(String fileName)
{
InputStream in;
byte [] signature;
X509Certificate cert = null;
try
{
in = new FileInputStream(fileName);
CertificateFactory factory = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) factory.generateCertificate(in);
signature = cert.getSignature();
System.out.println("Signature Algorithm: " + cert.getSigAlgName());
System.out.println(signature);
return cert;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (CertificateException e)
{
e.printStackTrace();
}
return cert;
}