【问题标题】:Import a persistent key in to Windows key storage using CNG storage functions使用 CNG 存储功能将持久密钥导入 Windows 密钥存储
【发布时间】:2015-05-08 13:44:46
【问题描述】:

我正在尝试将持久性 RSA 公钥导入密钥存储。我在CNG help page 上读到,私钥是可能的,我想知道我是否也可以将其应用于公钥(特别是 BCRYPT_RSAPUBLIC_BLOB)。我尝试使用以下代码,但在导入部分,当我调用 NCryptSetProperty 将公共 blob 设置为属性时,我得到“错误 0x80090029”,这是 NTE 错误数据。无法调试此功能失败的原因。

NCRYPT_PROV_HANDLE providerHandle = NULL;
NCRYPT_KEY_HANDLE keyHandle = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
PBYTE blob = NULL;
DWORD blob_len = 0;

///////////////////Export Test (extract key from storage)///////////////////////////

// Open handle to the Key Storage Provider
if(FAILED(status = NCryptOpenStorageProvider(
    &providerHandle,            //OUT: provider handle
    MS_KEY_STORAGE_PROVIDER,    //IN: Microsoft key storage provider
    0)))                        //IN: dwFlags (unused)
{
    //report fail
}

// Open key in the Key Storage Provider
if (FAILED(status = NCryptOpenKey(
    providerHandle,
    &keyHandle,
    keyName.c_str(),
    0,
    0)))
{
    //report fail
}

// (2 step key extraction process) 1. Get size of key
if (FAILED(status = NCryptExportKey(
    keyHandle,              //IN: Handle of the key to export
    NULL,                   //IN(opt): key used to encrypt exported BLOB data   <-- potentially an safer way for key extraction, encrypt it with a key during extraction (decrypt with NCryptDecrypt)
    BCRYPT_RSAPUBLIC_BLOB,  //IN: BLOB type (https://msdn.microsoft.com/en-us/library/windows/desktop/aa376263%28v=vs.85%29.aspx)
    NULL,                   //IN(opt): List of paramters for the key
    NULL,                   //OUT(opt): Output byte buffer
    0,                      //IN:  Size of the output buffer
    &blob_len,              //OUT: Amount of bytes copied to the output buffer
    0)))                    //IN: Flag to modify function behaviour (0 means no flag set)
{
    //report fail
}

// Allocate data blob to store key in
blob = (PBYTE)malloc(blob_len); 
if (NULL == blob) {
    //report fail
}

// (2 step key extraction process) 2. Get key and store in byte array (Extracted key is in form of BCRYPT_RSAKEY_BLOB)
if (FAILED(status = NCryptExportKey(
    keyHandle,
    NULL,
    BCRYPT_RSAPUBLIC_BLOB,
    NULL,
    blob,
    blob_len,
    &blob_len,
    0)))
{
    //report fail
}


///////////////Import Test (Store into storage)//////////////////////////////////////////////

// Create a persisted key
if(FAILED(status = NCryptCreatePersistedKey(
    providerHandle,             //IN: provider handle
    &keyHandle,                 //OUT: Handle to key
    NCRYPT_RSA_ALGORITHM,       //IN: CNG Algorithm Identifiers. NCRYPT_RSA_ALGORITHM creates public key
    keyName.c_str(),            //IN: Key name. If NULL, the key does not persist 
    0,                          //IN: Key type
    NCRYPT_OVERWRITE_KEY_FLAG)))//IN: Behaviour: 0 - apply to current user only, NCRYPT_MACHINE_KEY_FLAG - apply to local comp only, NCRYPT_OVERWRITE_KEY_FLAG - overwrite existing key
{
    //report fail
}

// Set the size of the key
if(FAILED(status = NCryptSetProperty(
    keyHandle,                          //IN: Handle to key
    BCRYPT_RSAPUBLIC_BLOB,              //IN: CNG Algorithm Identifiers. BCRYPT_RSAPUBLIC_BLOB allows me to use set this blob as the new key's blob
    blob,                               //IN: Key name. If NULL, the key does not persist 
    blob_len,                           //IN: Key Length
    0)))                                //IN: Bahaviour: 0 - apply to current user only, NCRYPT_MACHINE_KEY_FLAG - apply to local comp only, NCRYPT_OVERWRITE_KEY_FLAG - overwrite existing key
{
    //report fail <<-------------------------- Fail here
}

// Finalize key generation (Key is now usable, but uneditable) 
if(FAILED(status = NCryptFinalizeKey(keyHandle, 0)))            {
    //report fail
}
////////////////////////////////////////////////////////////////////////

【问题讨论】:

  • 我对自己没有阅读更多内容感到有点失望,但我看到一个宣传语说: >“对于 BCryptExportKey 创建持久密钥对,输入密钥 BLOB 必须包含私钥。公钥不会持久化。”这意味着我不应该像公共 blob 一样创建持久密钥。

标签: c++ key blob cng


【解决方案1】:

在创建非对称密钥时,可以设置的属性之一是 NCRYPT_EXPORT_POLICY_PROPERTY。我用它来控制是否可以读取私有。

//... after NCryptCreatePersistedKey()

    DWORD export_policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

    if(FAILED(status = NCryptSetProperty(
        keyHandle,
        NCRYPT_EXPORT_POLICY_PROPERTY,
        (PBYTE)&export_policy,  
        static_cast<DWORD>(sizeof(DWORD)),
        NCRYPT_PERSIST_FLAG | NCRYPT_SILENT_FLAG)))
    {
        //report error
    }

//... before NCryptFinalizeKey()

这里定义了属性。 https://msdn.microsoft.com/en-us/library/windows/desktop/aa376242(v=vs.85).aspx

【讨论】:

    猜你喜欢
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    相关资源
    最近更新 更多