2

我有一个 base 64 二进制格式的证书 x509。如何使用 Oracle 检索有关证书的信息?我必须得到这个证书的序列号。有任何想法吗?

4

2 回答 2

2

Oracle 论坛上有一个解决方案:SQL to extract specific attributes from an x​​509 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
于 2016-04-15T20:29:35.317 回答
0

在对证书进行 base64 解码后,您很可能会获得 X.509 v3 证书的 DER 编码 ASN.1 结构(足够的关键字可以继续搜索答案)。

我不知道 ASN.1 解析器的任何 PL/SQL 实现,解析 DER 编码的内容,但是可以学习 ASN.1 结构(序列、整数等)及其 DER 格式的二进制表示,然后在 PL/SQL 中逐字节进行解析。=> 序列号接近 DER-content 的开头,所以不需要支持解析每个 ASN.1 元素来提取序列号。

您可能必须查看 X.509证书结构/模板,解释如何从基本 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 的书籍。

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

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

于 2013-08-16T09:31:21.907 回答