2

オブジェクト識別子の16進バージョンを取得する[プログラミング言語固有ではない]方法はありますか?

元:

OID 1.2.840.10040.4.1:dsa

16進文字列=2a86 48 ce 38 04 01

それらのリストにアクセスするのは簡単ではないようです。X509証明書で使用されるOIDを探しています

4

4 に答える 4

6

を使用CryptEncodeObjectExして、OIDを含む最も暗号化されたオブジェクトをデコードできます。

OIDの場合、エンコードとデコードは非常に簡単なので、手動で行うことができます。

最初の2つの数値1.2は、少し特別な方法でエンコードされます。たとえば、xyは40 * x+yとしてエンコードされます。1.2の場合、40 * 1 + 2=42または0x2aになります。

次のすべての文字は7ビットの数値として解釈されます。最上位のビット(0から始める場合はビット番号7)は0で、最後のバイトは1で、最後のビットでない場合は1です。たとえば、840は0x348です。これをエンコードするには、最後の2バイトを使用する必要があります。0x48が保存されます。前のものでは、0x48からの追加ビットで0x3を保存する必要があります(8ビットエンコーディングではなく7ビットコーディングのため)。したがって、最初のバイトで0x3 * 2=0x6をエンコードする必要があります。0x6は整数のエンコードの最後のバイトではないため(0x48バイトが続きます)、エンコードされた値に0x80を追加する必要があります。したがって、0x80 + 0x6=0x86を受け取ります。したがって、840は0x86および0x48としてエンコードされます。

同様に、10040は0x2738です。最後のバイトは0x38で、最初のバイトは0x27 * 2(7ビットコーディングのため):0x27 * 2=0x4eです。0x4eは最後のバイトではないため、エンコードされた値に0x80を追加する必要があります:0x4e + 0x80=0xce。したがって、10040は2バイトの0xceと0x38としてエンコードされます。

4と1は、0x04と0x01と同じようにエンコードされます。

したがって、1.2.840.10040.4.1は、すでに知っているように2a 86 48 ce 380401としてエンコードする必要があります。

これはすべて、ITU-T X.690(ISO / IEC 8825-1)の8.19で読むことができます。

コメントに基づいて更新:エンコード/デコードプログラムに問題があります。OID「1.2.840.113549.1.1.1」は、あなたが書いたように2A 86 48 86 F7 0D 01 01 01ではなく、として表されます。2a 86 48 83 f6 8d 01 01 01これを確認するには、次の小さなCプログラムを使用できます。

#define STRICT
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#pragma comment (lib, "Crypt32.lib")

void PrintOffset(DWORD dwMargineOffset)
{
    while (dwMargineOffset--)
        _tprintf (TEXT(" "));
}

void HexDump (PBYTE pData, DWORD dwDataLength)
{
    while (dwDataLength--) {
        _tprintf (TEXT("%02X"), *pData++);
        if (dwDataLength) _tprintf (TEXT(" "));
    }
}

void DumpOID (DWORD dwMargineOffset, PBYTE pData, DWORD dwDataLength)
{
    PCCRYPT_OID_INFO pCryptOidInfo;
    DWORD dw, i;
    char szOID[256];
    // i
    // first byte is encoded as x.y 40*x+y = 43 = 0x2B
    //
    //_tprintf(TEXT("%d.%d"), *pData/40, *pData%40);
    i = wsprintfA (szOID, "%d.%d", *pData/40, *pData%40);
    dwDataLength--;
    pData++;

    while (dwDataLength--) {
        if (*pData & 0x80) {
            dw = 0;
#pragma warning(disable:4127)
            while (TRUE) {
#pragma warning(default:4127)
                dw <<= 7;  // *128
                dw += (*pData & 0x7F);
                if (*pData++ & 0x80)
                    dwDataLength--;
                else
                    break;
            }
            //_tprintf(TEXT(".%d"), dw);
            i += wsprintfA (szOID+i, ".%d", dw);
        }
        else
            //_tprintf(TEXT(".%d"), *pData++);
            i += wsprintfA (szOID+i, ".%d", *pData++);
    }

    PrintOffset(dwMargineOffset);
    _tprintf (TEXT("%hs"), szOID);

    // try find OID in the list of known IODs
    pCryptOidInfo = CryptFindOIDInfo (CRYPT_OID_INFO_OID_KEY, szOID, 0);
    if (pCryptOidInfo)
        _tprintf (TEXT(" (\"%ls\")"), pCryptOidInfo->pwszName);
    else
        _tprintf (TEXT(" (Unknown OID)"));
}

int main()
{
    BOOL bIsSuccess;
    DWORD cbEncoded = 0;
    PBYTE pbyData = NULL;
    BYTE byData[] = {0x2a, 0x86, 0x48, 0x83, 0xf6, 0x8d, 0x01, 0x01, 0x01};
    BYTE byData2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01};
    LPSTR pszOid = "1.2.840.113549.1.1.1";
    DumpOID (0, byData, sizeof(byData));
    _tprintf (TEXT("\n"));
    DumpOID (0, byData2, sizeof(byData2));
    _tprintf (TEXT("\n"));

    bIsSuccess = CryptEncodeObjectEx (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
                                      X509_OBJECT_IDENTIFIER,
                                      (const void *)&pszOid,
                                      CRYPT_ENCODE_ALLOC_FLAG,
                                      NULL,
                                      &pbyData,
                                      &cbEncoded);
    if (bIsSuccess) {
        HexDump (pbyData, cbEncoded);
        _tprintf (TEXT("\n"));
        pbyData = (PBYTE) LocalFree (pbyData);
    }

    return 0;
}

プログラムは次の出力を生成します06 09 2A 86 48 86 F7 0D 01 01 01。ここで、BERエンコードの最初のバイト0x06はOIDデータ型を意味し、次のバイト0x09はデータ長を意味し、次の9バイト2A 86 48 86 F7 0D 01 01 01はエンコードされたOID1.2.840.113549.11.1です。

プログラムの完全な出力は次のとおりです。

1.2.840.8226433.1.1 (Unknown OID)
1.2.840.113549.1.1.1 ("RSA")
06 09 2A 86 48 86 F7 0D 01 01 01
于 2010-08-03T23:59:29.237 に答える
2

0〜65536(0xFFFF)の値に変換する方法を説明しました。

より高い値の計算について説明していただけますか?113549のように?

于 2012-03-24T23:07:44.860 に答える
1

私はついにそれを手に入れました。ありがとうございました。RSAエンコーディングのシーケンスを作成しました。(RSADSIが113549の場合)

113549は1bb8d(ヘキサ)です

バイナリ形式として、1bb8dは0001 1011 101110001001です。

これは7ビットエンコーディングであるため、次のように表されます。

00 0110 | 111 0111 | 0001001

=> 0x06 | 0x77 | 0x0d

=> 0x06 + 0x80 | 0x77 + 0x80 | 0x0d

=> 0x86 0xf7 0x0d

====================================

0x86 | 0xf7 | 0x0d

于 2013-07-12T05:32:21.190 に答える
0

にとって113549

ヘキサ:1bb8d

バイナリ:0001 1011 1011 1000 1101

ステップ1:7ビットを使用してグループを作成します。

*0*0001 10 |11 1011 1 |000 1101

ステップ2:ビットに8ビットを追加します(0右端のバイトのみに1追加され、他のすべてのバイトに追加されます):

*1*000 0110 | *1*111 0111 | *0*000 1101

ステップ3: 2進数を16進数に変換します。

0x86 | 0xf7 | 0x0d

于 2015-11-05T16:46:05.777 に答える