2017-03-28 128 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