在Oracle存储过程中解析基本64 X509证书



我有一个基本64二进制格式的证书x509。如何使用Oracle检索有关证书的信息?我必须获得此证书的序列号。有什么想法吗?

Oracle论坛上有一个解决方案:SQL可以从X509数字证书中提取特定属性

代码(原件是用于存储为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

base64-decode a证书后,您很可能会获得der-der-decreded asn.1 X.509 V3证书的结构(足够的关键字可以继续搜索答案)。/p>

我不知道ASN.1解析器的任何PL/SQL实现,解析编码的内容,但是可以学习ASN.1结构(序列,整数等)及其二进制表示形式,然后在pl/sql中进行解析,字节由字节进行。=>序列号接近der-content的开头,因此您无需支持分析每个asn.1元素即可提取序列号。

您可能必须查看X.509证书结构/模板,以解释如何从基本ASN.1元素构造的证书,然后解析/提取元素并获取您感兴趣的信息。

证书中的内容的更详细说明:X.509证书由一些数据字段组成,例如版本,序列号,有效/到日期,发行人DN(杰出名称),主题DN,主题DN,主题公钥,签名哈希算法等等。然后,该信息由证书发行人"签名":发行人从上面提到的信息中创建哈希代码(例如使用SHA-1算法),然后使用发行人的私钥(RSA Encryption)对其进行加密。拥有发行人的公钥并信任发行人,可以使用发行人的公钥解密发行人加密的哈希代码,然后使用同一算法从证书详细信息中创建哈希代码,最后将计算的哈希与发行人进行比较。创建。如果这些匹配,则意味着没有人修改详细信息,因此,如果信任发行人,也可以信任证书中的详细信息。

X.509证书以(右图显示的数据类型)开头:

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

每个元素以标记字节指示元素类型开头,然后是元素长度,然后是元素内容。如果元素包含少于128个字节,则长度字段仅需要一个字节来指定内容长度。如果超过127个字节,则长度字段的位7设置为1,位6至0指定用于识别内容长度的附加字节的数量。对于X.509证书,版本包裹在上下文特定标签[0]。

解释ASN.1的书籍可以从网络上免费下载。

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
    ...

当然,在您的情况下,序列号的长度可能大于此处显示的一个字节。

最新更新