본문 바로가기
Jop Study

SNMP OID 계산 방법

by 누누데디 2021. 2. 9.
반응형

CryptEncodeObjectExOID를 포함한 대부분의 암호화 개체를 디코딩하는 데 사용할 수 있습니다 .

OID의 경우 인코딩 및 디코딩이 매우 간단하므로 수동으로 수행 할 수 있습니다.

두 개의 첫 번째 숫자 1.2는 약간 특별한 방법으로 인코딩됩니다. 예를 들어 xy는 40 * x + y로 인코딩됩니다. 1.2의 경우 40 * 1 + 2 = 42 또는 0x2a입니다.

모든 다음 문자는 가장 높은 비트 (0으로 시작하는 경우 비트 번호 7)가 0이면 바이트가 마지막이고 비트가 마지막이 아닌 경우 1 인 7 비트 숫자로 해석됩니다. 예를 들어 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 38 04 01로 인코딩되어야합니다.

이 모든 것은 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가 인코딩 된 OID 1.2.840.113549.1.1.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

 

1

드디어 얻었습니다. 감사합니다. RSA 인코딩 시퀀스를 작성했습니다. (RSADSI가 113549 인 경우)

113549는 1bb8d (Hexa)입니다.

바이너리 형식으로 1bb8d는 0001 1011 1011 1000 1001입니다.

7 비트 인코딩이므로 다음과 같이 표현됩니다.

00 0110 | 111 0111 | 000 1001

=> 0x06 | 0x77 | 0x0d

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

=> 0x86 0xf7 0x0d

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

0x86 | 0xf7 | 0x0d

반응형

'Jop Study' 카테고리의 다른 글

유해인자 취급 및 관리대장 작성  (0) 2021.11.02
RS232 TTL, RS232 Voltage Level 정의  (0) 2021.01.15
core의 용어  (0) 2020.11.13
Core 재질에 따른 특성  (0) 2020.11.13
홀드 업 시간에 필요한 커패시턴스 계산식  (0) 2020.11.09