将数据(结构)写入文件

时间:2018-06-20 10:36:53

标签: c

好吧,我有一个功能:

CRYPT_PRIVATE_KEY_INFO *pPriKeyInfo = NULL;
DWORD cbPriKeyInfo = 0;
SxKS_ExportPKCS8_PriKeyInfo(
            pKey,
            &pPriKeyInfo,
            &cbPriKeyInfo);

将存储密钥(私有密钥)导出为特定结构的私有密钥:

typedef struct _CRYPT_PRIVATE_KEY_INFO{
    DWORD                       Version;
    CRYPT_ALGORITHM_IDENTIFIER  Algorithm;
    CRYPT_DER_BLOB              PrivateKey;
    PCRYPT_ATTRIBUTES           pAttributes;
}  CRYPT_PRIVATE_KEY_INFO, *PCRYPT_PRIVATE_KEY_INFO;

我需要将这种结构的数据写入文件:

FILE *fp;
fp = fopen("c:\\CRYPT_PRIVATE_KEY_INFO.pem", "wb");
fwrite(&pPriKeyInfo, sizeof(pPriKeyInfo), cbPriKeyInfo, fp);
fclose(fp);

问题是,我做对了吗?因为我认为我得到了错误的数据。

2 个答案:

答案 0 :(得分:1)

您正在将 pointer 写入文件。指针指向特定于当前正在运行的进程的内存。如果您将指针加载到另一个进程中,即使是运行同一程序的另一个进程,则该指针也将无效。

一个快速解决方案是不要将指针写入文件,而是将结构写入文件。

然而 ,由于结构中的成员之一是指针,这将导致再次发生同样的问题。您需要做的是serialize结构。

答案 1 :(得分:0)

fwrite(&pPriKeyInfo, sizeof(pPriKeyInfo), cbPriKeyInfo, fp);

您对fwrite()的调用的前三个参数是错误的。他们告诉fwrite()要在文件中写些什么,所以毫无疑问为什么存储在文件中的数据看起来不好。

通常如何使用fwrite()函数

fwrite()的第一个参数是指向要写入的数据的指针。 fwrite()可以写一个对象数组,它的第一个参数是要写的第一个对象的地址。

pPriKeyInfo本身就是您要写入文件的数据的指针。将&pPriKeyInfo传递到fwrite()没有任何意义。您不必关心pPriKeyInfo的值,而只关心它指向的数据。

fwrite()的第二个参数是要写入文件的每个对象的大小。它应该是第一个参数(CRYPT_PRIVATE_KEY_INFO)所指向的结构的大小。

fwrite()的第三个参数是要写入的对象数。在您的示例中,它应该为1

总而言之,对fwrite()的调用应类似于:

fwrite(pPriKeyInfo, sizeof(CRYPT_PRIVATE_KEY_INFO), 1, fp);

但是等等,它仍然无法保存正确的数据!

上面的解释假设作为第一个参数传递给fwrite()(类型为CRYPT_PRIVATE_KEY_INFO的结构)的对象包含要写入文件中的实际数据。

struct CRYPT_PRIVATE_KEY_INFO并非如此。这是它的定义:

typedef struct _CRYPT_PRIVATE_KEY_INFO {
  DWORD                      Version;
  CRYPT_ALGORITHM_IDENTIFIER Algorithm;
  CRYPT_DER_BLOB             PrivateKey;
  CRYPT_ATTRIBUTES           *pAttributes;
} CRYPT_PRIVATE_KEY_INFO, CRYPT_PRIVATE_KEY_INFO, *PCRYPT_PRIVATE_KEY_INFO;

如您所见,字段pAttributes是指向CRYPT_ATTRIBUTES结构的指针,而其他两个结构字段(AlgorithmPrivateKey)本身也包含指针。 / p>

这绝对不是将CRYPT_PRIVATE_KEY_INFO结构保存在文件中的正确方法而且从它包含的大量指针中,我认为这种结构设计用于内存中,而不是保存。

对于我来说,尚不清楚要保存到文件中的确切内容,但是从文档中看来,实际的密钥存储在结构的PrivateKey成员中。要将其写入文件,您可以使用:

fwrite(pPriKeyInfo->PrivateKey.pbData, sizeof(BYTE), pPriKeyInfo->PrivateKey.cbData, fp);