【发布时间】:2017-03-28 15:01:20
【问题描述】:
我想了解如何签署 x.509 证书。
我已设置 OpenSSL CA 来创建演示证书。证书很好,我可以使用名为 dumpasn1 的工具查看所有相关元素。 从理论上讲,我知道我必须签署名为“tbsCertificate”的结构,该结构复合属性版本、序列号签名、发行者、有效性、主题、subjectPublicKeyInfo 和扩展。
但是,当我尝试在 Java 中模仿它时,不幸的是它不起作用。 我要做的是:
- 我阅读了 DER 编码证书的“tbsCertificate”部分
- 然后我从颁发 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;
}
【问题讨论】:
标签: java certificate x509 signing asn.1