Openssl

OID 2a 86 48 86 f7 0d 如何解析為 1.2.840.113549?

  • March 29, 2021

我看到由 OpenSSL 創建的 RSA 密鑰包含以下 HEX 字元串:

2a 86 48 86 f7 0d 01 01 01

該 HEX 字元串被解釋為對象 ID:

1.2.840.113549.1.1.1

很明顯 01 01 01 是 1.1.1,但是 2a 86 48 86 f7 0d 如何被解釋(解析)為 1.2.840.113549?

問題的字節串是類型為 6 的ASN.1 BER/DER TLV2a 86 48 86 f7 0d 01 01 01的值欄位,它是 RSA 密鑰的對象標識符(之前的類型和長度編碼為,不再進一步討論)。06 09

為了解析該值字節串,我們首先將字節分成塊,這些塊在高位被清除的每個字節之後結束(換句話說:塊在 00 h到 7f h範圍內的字節之後結束)。然後我們將字節的低 7 位粘貼在一起(按大端/讀取順序);這樣

_____2a|_____86_____48|_____86_____f7_____0d|_____01|_____01|_____01   就變成了

0101010|00001101001000|000011011101110001101|0000001|0000001|0000001

然後,我們將每個位塊解釋為以大端二進制編碼一個非負整數。問題的範例現在顯示為六個整數:42 840 113549 1 1 1

第一個整數有一個特殊情況:它被建構為 $ z=40x+y $ , 和 $ x $ 編碼分配的頂級權限 $ y $ . 整數 $ x $ 總是其中之一 $ 0 $ (對於ccitt), $ 1 $ (對於iso)或 $ 2 $ (對於joint-iso-ccitt),如果 $ x<2 $ 然後 $ y<40 $ .

因此,我們替換第一個整數 $ z $ 經過 $ x=\min(\lfloor z/40\rfloor,2) $ 和 $ y=z-40x $ .

注意:當 $ x=2 $ , $ y $ 可以任意大。已分配 $ y $ 包括40 (行使 $ \min $ 規則),48(需要編碼 $ z $ 超過一個字節),和999(與 $ y\ge2^8 $ ),某些現有軟體可能無法正確處理。

問題的範例現在顯示為七個整數:1 2 840 113549 1 1 1

一種做法是將這些整數格式化為十進制,不帶前導0數字(表示為 的整數零除外0),用點分隔,如在

1.2.840.113549.1.1.1

或有時括在帶有分隔空格的大括號中,如 in

{1 2 840 113549 1 1 1}

或有時(如OID所示Repository )

{iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) rsaEncryption(1)}

OID-IRI 表示法

/ISO/Member-Body/840/113549/1/1/1

細心的讀者會注意到,根據上述約定,不同的字節串可以解碼為相同的 OID;然而,加密規則(至少對於 OID)是堅持唯一的DER 編碼,這樣(在具有 OID 的 Value 欄位的位串中)一個字節 80 h只能跟隨一個設置了高位的字節(否則 80 h將編碼整數的前導零,並且必須被抑制)。


Daniel Marschall關於 OID 編碼和大小限制的研究對於使上述(希望)正確是最有用的;它也證實了我的直覺,即 OID 解碼實踐是混亂的。微軟有一個關於 OID 格式的解釋,我發現它最初很有用,即使它被證明是危險的缺乏。

OID 編碼的規範參考在IUT-T X.680 到 X.695 Information Technology - Abstract Syntax Notation One (ASN.1) & ASN.1 encoding rules中的某處。它們也在其自由祖先IUT-T X.209:1988 Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1) in section 22 Encoding of an object identifier value中,在IUT-T X.208 中有定義: 1988 年規範抽象語法符號一 (ASN.1)在第 28 節中對象標識符類型的符號和附件 B、C 和 D。

引用自:https://crypto.stackexchange.com/questions/29115