2017-03-28 80 views
0

我想了解如何签名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; 
} 

回答

0

ECDSA不会产生稳定的签名,所以如果您的测试是您产生了相同的答案,将无法正常工作。您可以通过验证针对tbsCertificate数据呈现的签名来验证证书上的签名。

你的做法将与RSA签名工作,因为这是一个稳定的签名算法(PKCS1填充,不与PSS)。

作为认定即tbsCertificate:你似乎有DER编码是什么的想法,但我觉得有必要基于松散的描述中的问题提供指导:的

二进制编码形式证书在DER中。第一个字节将是0x30((构造)SEQUENCE)。下一个字节是序列的长度(< 0x80)或长度是多长(0x82 =>接下来的两个字节是大端长度)。下一个字节将再次为0x30,即tbsCertificate编码值的开始。然后,您可以读取该结构的长度,并计算tbsCertificate的正确结束偏移量。

证书结构可以RFC 3280找到。 (在RFC 5280有一个更新,但我听到有人说“没有被批准作为标准”)。它也可以与属性证书一起在ITU-T X.509 - 这是X的地方。X.509证书中的509来自。我链接到2012版本,因为2016版本位于付费墙后面。

+0

感谢您的回答。我知道DER编码,它以一个序列开头。我只是不想再提出这个问题而且更复杂。我也知道RFC 3280,它对于tbsCertificate或多或少都很清楚。如果我正确解释它,它应该以偏移4处的第二个“SEQUENCE”字节开始,并延伸到给定的长度。 你说ECDSA不会产生稳定的签名是什么意思?我想完全按照你所描述的 - 我想通过tbsCertificate运行签名算法来重新创建签名。 我认为 –

+0

我想我现在理解稳定的含义 - 感谢您对此事的评论。我曾想过我可以重新创建签名。 感谢您的提示,我试图重新签署测试认证,它似乎工作。当我验证修补证书时,它确认无误。 –

+0

很高兴我可以帮助:)。 StackOverflow礼仪上的“谢谢”:如果答案正确,请标记。如果它有帮助,你也可以选择注册。 – bartonjs