Base 64 バイナリ形式の証明書 x509 があります。Oracle で証明書に関する情報を取得するにはどうすればよいですか? この証明書のシリアル番号を取得する必要があります。何か案は?
2 に答える
Oracle フォーラムに解決策があります: x509 デジタル証明書から特定の属性を抽出する SQL
コード (元は 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 でデコードすると、ほとんどの場合、DER でエンコードされた X.509 v3 証明書の ASN.1 構造が得られます (回答を検索し続けるのに十分なキーワードです)。
DER でエンコードされたコンテンツを解析する ASN.1 パーサーの PL/SQL 実装については知りませんが、ASN.1 構造 (シーケンス、整数など) とその DER 形式でのバイナリ表現を学習することは可能です。 PL/SQLでバイトごとに解析を行います。=> シリアル番号は DER コンテンツの先頭に近いため、シリアル番号を抽出するためにすべての 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 バイト未満の場合、コンテンツの長さを指定するために長さフィールドに必要なのは 1 バイトだけです。127 バイトを超える場合、Length フィールドのビット 7 は 1 に設定され、ビット 6 から 0 は、コンテンツの長さを識別するために使用される追加のバイト数を指定します。X.509 証明書の場合、バージョンはコンテキスト固有のタグ [0] でラップされます。
ASN.1 を説明する書籍は、Web から無料でダウンロードできます。
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 バイトよりも大きい場合があります。