我想了解如何签名x.509证书。在Java中签名X.509证书
我设置了一个CA的OpenSSL创建示范证书。证书没问题,我可以使用名为dumpasn1的工具查看所有相关元素。 理论上我知道我必须签署名为“tbsCertificate”的结构,它将属性版本,序列号签名,颁发者,有效性,主题,subjectPublicKeyInfo和扩展组合在一起。
然而,当我试图模仿,在Java中,遗憾的是它不工作。 我要做的就是:
- 我读了DER编码证书“即tbsCertificate” -portion
- 然后我从颁发CA获取私有密钥
- 最后我尝试登录该tbsCertificate-结构通过使用下面的代码:
。
public static void sign(byte [] data) throws Exception
{
String algorithm = "SHA256withECDSA";
PrivateKey privKey;
KeyPair keyPair;
keyPair = getKeyPairFomPEM();
privKey = keyPair.getPrivate();
Signature ecdsa;
ecdsa = Signature.getInstance(algorithm, "BC");
ecdsa.initSign(privKey);
ecdsa.update(data);
byte[] baSignature = ecdsa.sign();
}
不幸的是,结果不匹配的证书中的签名,所以很明显我做了某种错误。 签名算法与证书(SHA256withECDSA)中使用的相同,所以我怀疑我没有选择tbsCertificate结构的正确部分。
我的证书长约530个字节。我从偏移量4开始读取(跳过初始SEQUENCE标记和长度字节)到扩展的末尾(在证书部分开始之前停止)。
谁能告诉我们,如果这是我要读为“即tbsCertificate”结构中的字节数组的权利? 还有什么其他的错误可能让我现在看不到? 证书本身确实没问题,我使用以下Java代码对证书和签名算法进行了双重检查。
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;
}
感谢您的回答。我知道DER编码,它以一个序列开头。我只是不想再提出这个问题而且更复杂。我也知道RFC 3280,它对于tbsCertificate或多或少都很清楚。如果我正确解释它,它应该以偏移4处的第二个“SEQUENCE”字节开始,并延伸到给定的长度。 你说ECDSA不会产生稳定的签名是什么意思?我想完全按照你所描述的 - 我想通过tbsCertificate运行签名算法来重新创建签名。 我认为 –
我想我现在理解稳定的含义 - 感谢您对此事的评论。我曾想过我可以重新创建签名。 感谢您的提示,我试图重新签署测试认证,它似乎工作。当我验证修补证书时,它确认无误。 –
很高兴我可以帮助:)。 StackOverflow礼仪上的“谢谢”:如果答案正确,请标记。如果它有帮助,你也可以选择注册。 – bartonjs