微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CNG/BCrypt/NCrypt 导入用持久 RSA 密钥包装的临时 AES 密钥

如何解决CNG/BCrypt/NCrypt 导入用持久 RSA 密钥包装的临时 AES 密钥

我将编写某种安全客户端/服务器对:

  • 服务器部分提供封装的 AES 密钥。
  • 客户端部分基于 CNG win32 API (ncrypt.h+bcrypt.h),将请求服务器发送一些密钥(在需要时)。

这是我的计划:

  1. 在客户端:
    • 我一次性创建了一个持久性 RSA 密钥 (NCryptCreatePersistedKey)
    • 我导出此密钥的公共部分 (NCryptExportKey + BCRYPT_RSAPUBLIC_BLOB)
    • 我将此公钥发送到服务器(格式待定
  2. 在服务器端:
    • 生成一个随机的 AES 密钥
    • 我使用收到的公钥包装它
    • 我将包装好的 AES 密钥发回给客户端(格式 TBD
  3. 回到客户端:
    • 提取包装好的密钥并将其序列化为 BCrypt 兼容的 blob。
      ->如何构建 BCrypt blob?
    • 将包装好的 AES 密钥导入为临时密钥 (BCryptImportKey)
      -> 如何导入用持久性非对称密钥包装的临时对称密钥?
    • 现在我可以使用这个 AES 密钥来加密/解密数据...

我编写了一个应该工作的代码,但它仍然存在一些灰色区域...
代码如下:

void get_wrapped_aes_key ( PUCHAR rsa_pub_key_blob,ULONG rsa_pub_key_blob_size,PUCHAR wrapped_aes_key_blob,PULONG wrapped_aes_key_blob_size )
    {
    // send the rsa public key (from buffer rsa_pub_key_blob) to the secu server
    // secu server generates a random AES key and wraps it with the rsa public key
    // receive the wrapped AES key and serialize it into a BCrypt blob
    // mem copy this blob into the buffer wrapped_aes_key_blob)
    }

void create_persistent_key ( const wchar_t * key_name )
    {
    const wchar_t      * storage          = MS_PLATFORM_CRYPTO_PROVIDER ;
    NCRYPT_PROV_HANDLE   storage_provider = NULL ;
    NCRYPT_KEY_HANDLE    rsa_key          = NULL ;

    NCryptOpenStorageProvider( &storage_provider,storage,0 ) ;
    NCryptCreatePersistedKey( storage_provider,&rsa_key,BCRYPT_RSA_ALGORITHM,key_name,NCRYPT_OVERWRITE_KEY_FLAG ) ;
    NCryptFinalizeKey( rsa_key,0 ) ;
    NCryptFreeObject( rsa_key ) ;
    NCryptFreeObject( storage_provider ) ;
    }

BCRYPT_KEY_HANDLE import_key_using_persistent_key ( const wchar_t * key_name )
    {
    const wchar_t      * storage          = MS_PLATFORM_CRYPTO_PROVIDER ;
    const wchar_t      * blob_type        = BCRYPT_RSAPUBLIC_BLOB ;
    BCRYPT_ALG_HANDLE    algo_provider    = NULL;
    NCRYPT_PROV_HANDLE   storage_provider = NULL;
    NCRYPT_KEY_HANDLE    rsa_key          = NULL;
    BCRYPT_KEY_HANDLE    bcrypt_rsa_key   = NULL;
    BCRYPT_KEY_HANDLE    imported_aes_key = NULL;
    BYTE                 rsa_pub_key_blob [500] ;
    DWORD                rsa_pub_key_blob_size = sizeof(rsa_pub_key_blob) ;
    BYTE                 wrapped_aes_key_blob [500] ;
    DWORD                wrapped_aes_key_blob_size = sizeof(wrapped_aes_key_blob) ;

    //------------------- retrieve the persistent key
    NCryptOpenStorageProvider( &storage_provider,0 ) ;
    NCryptOpenKey( storage_provider,0 ) ;
    NCryptExportKey( rsa_key,NULL,blob_type,rsa_pub_key_blob,rsa_pub_key_blob_size,&rsa_pub_key_blob_size,0 ) ;

    //------------------- get a symmetric key from the security server
    get_wrapped_aes_key( rsa_pub_key_blob,wrapped_aes_key_blob,&wrapped_aes_key_blob_size ) ;

    // mysterIoUs conversion from  rsa_key  to   bcrypt_rsa_key 

    //------------------- import the security server
    BCryptOpenAlgorithmProvider( &algo_provider,0 ) ;
    BCryptImportKey( algo_provider,bcrypt_rsa_key,BCRYPT_KEY_DATA_BLOB,&imported_aes_key,wrapped_aes_key_blob_size,0 ) ;
    BCryptCloseAlgorithmProvider( algo_provider,0 ) ;
    NCryptFreeObject( storage_provider ) ;
    NCryptFreeObject( rsa_key ) ;
    return imported_aes_key ;
    }

由于服务端没有写,所以函数get_wrapped_aes_key还是空的,但是,顺便说一句:
如何构建包含封装的 AES 密钥的 blob?

函数 create_persistent_key 工作正常,但我有一个问题:如何选择 RSA 大小?
(它产生 2048 位密钥,这是我想要的,但我可以更改它吗?)

函数 import_key_using_persistent_key 中:BCryptImportKey 需要一个 BCRYPT_KEY_HANDLE 作为包装键,但我的持久键是一个 NCRYPT_KEY_HANDLE
我不知道该怎么做...

提前致谢

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?