我有一个基本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
...
当然,在您的情况下,序列号的长度可能大于此处显示的一个字节。