2012-10-28 85 views
2

我有一個基於64位二進制格式的證書x509。如何使用Oracle檢索有關證書的信息?我必須得到這個證書的序列號。有任何想法嗎?解析Oracle存儲過程中的base64 X509證書?

+0

什麼你的意思是'甲骨文',數據庫?請提供更多背景。 – home

+0

表示oracle數據庫存儲過程。 –

+0

在我的包體中,我正在通過webservice獲取base64證書。 webservice以xml格式返回base64binary中的證書。但我需要定義哪個序列號具有此證書。 –

回答

0

在對證書進行base64解碼之後,很可能會獲得X.509 v3證書的DER編碼ASN.1結構(足夠的關鍵字可以繼續搜索答案)。

我不知道ASN.1解析器的任何PL/SQL實現,解析DER編碼的內容,但可以學習DER中的ASN.1結構(序列,整數等)及其二進制表示格式,然後在PL/SQL中逐字節地進行解析。 =>序列號接近DER內容的開頭,因此您不需要支持解析每個ASN.1元素來提取序列號。

你可以來看看X.509 certificate structure/template,解釋如何證書是從基本的ASN.1元件構成,然後解析/提取的元素,讓你感興趣的信息。

更詳細描述證書內容:X.509證書由一些數據字段組成,例如版本,序列號,有效日期,頒發者DN(可分辨名稱),主題DN,主題公鑰,簽名散列算法等。此信息然後由證書頒發者「簽名」:頒發者從上述信息創建散列碼(例如使用SHA-1算法),然後使用頒發者的私鑰(RSA加密)對其進行加密。擁有發行人的公鑰並信任發行人,可以使用發行人的公鑰對發行人加密的哈希碼進行解密,然後使用相同的算法從證書詳細信息中創建哈希碼,最後將計算出的哈希與發行人的哈希碼進行比較創建。如果這些匹配,則意味着沒有人修改細節,因此如果發行人是可信的,證書中的細節也可以被信任。

X.509證書開始(右圖所示的數據類型):

Certificate    SEQUENCE 
    Data     SEQUENCE 
     Version   [0] { INTEGER } 
     Serial Number  INTEGER 

每個元素具有指示元素類型,其次是元件長度,隨後通過將元件內容的標記字節開始。如果元素包含少於128個字節,則長度字段僅需要一個字節來指定內容長度。如果超過127個字節,則長度字段的第7位被設置爲1,而第6到0位指定用於標識內容長度的附加字節的數量。在X.509證書的情況下,版本被封裝在特定於上下文的標籤[0]中。

從網絡上解釋ASN.1的書可以是downloaded for free

Here's an example for analysing the beginning of a certificate: 
    30 82 02 D7 30 82 02 40 A0 03 02 01 02 02 01 01 ... 
Interpretation: 
    30 = Start of Certificate SEQUENCE 
    82 = sequence length are the following two bytes 
    02 D7 = sequence length 0x02D7 (Big Endian order of bytes) 
    30 = Start of Data SEQUENCE 
    82 = sequence length are the following two bytes 
    02 40 = sequence length 0x0240 (Big Endian order of bytes) 
    A0 = start of context-specific element [0] 
    03 = length of context-specific element [0] 
    02 01 02 = content of context-specific element [0] (Version INTEGER) 
     (02=start of Version INTEGER, 
     01=length of the integer, 
     02=Version value (zero-based, so value 02 actually means v3)) 
    02 = Start of Serial Number INTEGER 
    01 = Length of Serial Number INTEGER 
    01 = The serial number itself 
    ... 

當然,在你的情況下,序列號的長度可能會比這裏顯示的一個字節大。

1

有在Oracle論壇的解決方案:SQL to extract specific attributes from an x509 digital certificate

代碼(原來是被存儲爲CLOB證書,我修改了它的BLOB和返回序列號):

create or replace and compile java source named testx509src 
as 
    import java.security.cert.*; 
    import java.io.*; 
    import java.sql.*; 
    import oracle.sql.BLOB; 
    import oracle.sql.NUMBER; 

    public class TestX509 { 
     public static NUMBER getSerialNumber(BLOB cert) 
       throws SQLException, IOException, CertificateException { 

      Connection conn = (Connection) DriverManager.getConnection("jdbc:default:connection:"); 
      BufferedInputStream is = new BufferedInputStream(cert.getBinaryStream()); 

      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      X509Certificate c = (X509Certificate) cf.generateCertificate(is); 
      is.close(); 

      return new oracle.sql.NUMBER(c.getSerialNumber()); 

     } 
    } 
/

CREATE OR REPLACE FUNCTION CERT_getSerialNumber(cert in blob) 
    RETURN NUMBER 
    AS LANGUAGE JAVA 
    NAME 'TestX509.getSerialNumber(oracle.sql.BLOB) return oracle.sql.NUMBER'; 
/

SQL> select CERT_GetSerialNumber(cert) serial from cert_storage where id = 1; 

serial 
----------------------- 
243435653237