【问题标题】:Parse pKIOverlapPeriod from LDIF export into days将 LDIF 导出中的 pKIOverlapPeriod 解析为天数
【发布时间】:2022-06-13 21:27:17
【问题描述】:

一些background to what I'm trying to achieve(不感兴趣的可以不用看,仅供参考)。

我已使用以下命令将 AD 中的证书模板导出到 LDIF 文件中:

ldifde -m -v -d "CN=MyTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=com" -f MyTemplate.ldf

模板包含以下记录:

pKIOverlapPeriod:: AICmCv/e//8=

看起来这是一个 base64 编码的Windows filetime structure,顶部可能有某种编码(?)。

来自微软的网站

FILETIME 结构是一个 64 位值,表示 自 1601 年 1 月 1 日以来经过的 100 纳秒间隔, 协调世界时 (UTC)。

我尝试将其解析为十六进制并得到0080a60affdeffff。但是,我想将其解析为“6 周”或“2 年”之类的内容。

因此,我编写了一个 Python 程序来解析 LDIF 并转换 pKIOverlapPeriod,但我没有得到预期的输出。

实际输出为:

pKIOverlapPeriod:
  unit: days
  value: 41911

由于我在证书模板中将重叠配置为“6 周”,因此这是我期望的输出:

pKIOverlapPeriod:
  unit: days
  value: 42

我使用的 Python 代码如下所示:

# pip3 install ldif pyyaml
from ldif import LDIFParser
import os
import sys
import json
import yaml

# Converts a Win32 FILETIME structure to a dictionary.
def filetime_to_dict(filetime):
    # This variable is supposed to contain the number of 100-nanosecond intervals since January 1, 1601...
    intervals = int.from_bytes(filetime, byteorder = 'big')
    return {
        "unit": "days",
        "value": int(intervals // (1E7 * 60 * 60 * 24))
    }

parser = LDIFParser(open(os.path.join(os.getcwd(), sys.argv[1]), "rb"))
for dn, records in parser.parse():
    template = {}
    for key in records:
        # Special magic for pKIOverlapPeriod goes here
        if key == 'pKIOverlapPeriod':
            template[key] = filetime_to_dict(records[key][0])
            continue
        # end of magic
        if len(records[key]) == 1:
            template[key] = records[key][0]
        else:
            template[key] = records[key]
    data = yaml.dump(
        yaml.load(
            json.dumps(template, default = str),
            Loader = yaml.SafeLoader),
        default_flow_style = False)
    print(data)

LDIF 如下所示:

dn: CN=AteaComputer,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=atea,DC=se
changetype: add
cn: AteaComputer
displayName: Atea Computer
distinguishedName: 
 CN=AteaComputer,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN
 =Configuration,DC=atea,DC=se
dSCorePropagationData: 20220601093015.0Z
dSCorePropagationData: 20220518190731.0Z
dSCorePropagationData: 16010101000000.0Z
flags: 131680
instanceType: 4
msPKI-Cert-Template-OID: 
 1.3.6.1.4.1.311.21.8.12474934.3506392.5459122.6785906.4016631.21.8298576.73677
 34
msPKI-Certificate-Application-Policy: 1.3.6.1.5.5.7.3.1
msPKI-Certificate-Application-Policy: 1.3.6.1.5.5.7.3.2
msPKI-Certificate-Name-Flag: 134217728
msPKI-Enrollment-Flag: 32
msPKI-Minimal-Key-Size: 256
msPKI-Private-Key-Flag: 101056512
msPKI-RA-Application-Policies: 
 msPKI-Asymmetric-Algorithm`PZPWSTR`ECDH_P256`msPKI-Hash-Algorithm`PZPWSTR`SHA2
 56`msPKI-Key-Usage`DWORD`16777215`msPKI-Symmetric-Algorithm`PZPWSTR`3DES`msPKI
 -Symmetric-Key-Length`DWORD`168`
msPKI-RA-Signature: 0
msPKI-Template-Minor-Revision: 1
msPKI-Template-Schema-Version: 4
name: AteaComputer
objectCategory: 
 CN=PKI-Certificate-Template,CN=Schema,CN=Configuration,DC=atea,DC=se
objectClass: top
objectClass: pKICertificateTemplate
pKICriticalExtensions: 2.5.29.15
pKIDefaultKeySpec: 1
pKIExpirationPeriod:: AEA5hy7h/v8=
pKIExtendedKeyUsage: 1.3.6.1.5.5.7.3.1
pKIExtendedKeyUsage: 1.3.6.1.5.5.7.3.2
pKIKeyUsage:: iA==
pKIMaxIssuingDepth: 0
pKIOverlapPeriod:: AICmCv/e//8=
revision: 104
showInAdvancedViewOnly: TRUE
uSNChanged: 53271
uSNCreated: 28782
whenChanged: 20220601093015.0Z
whenCreated: 20220518190731.0Z

我做错了什么?我已经交叉检查了我的实施,例如Python's winfiletime,结果相同,所以我开始怀疑需要先对字节进行解码,然后才能将其转换为 int。

【问题讨论】:

    标签: python active-directory pki ldif


    【解决方案1】:

    在摆弄这个之后,我想出了以下内容:

    def filetime_to_dict(filetime):
        input = 18446744073709551616 - int.from_bytes(filetime, byteorder = 'little')
        if intervals % (1E7 * 60 * 60 * 24 * 365) == 0:
            return {
                "unit": "years",
                "value": int(intervals / (1E7 * 60 * 60 * 24 * 365))
            }
        if intervals % (1E7 * 60 * 60 * 24 * 30) == 0:
            return {
                "unit": "months",
                "value": int(intervals / (1E7 * 60 * 60 * 24 * 30))
            }
        if intervals % (1E7 * 60 * 60 * 24 * 7) == 0:
            return {
            "unit": "weeks",
            "value": int(intervals / (1E7 * 60 * 60 * 24 * 7))
        }
        if intervals % (1E7 * 60 * 60 * 24) == 0:
            return {
                "unit": "days",
                "value": int(intervals / (1E7 * 60 * 60 * 24))
            }
        if intervals % (1E7 * 60 * 60) == 0:
            return {
                "unit": "hours",
                "value": int(intervals / (1E7 * 60 * 60))
            }
        return {
            "unit": "filetime",
            "value": filetime
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 2021-06-27
      相关资源
      最近更新 更多