使用秘密共享方案保护2048位RSA私钥的实现

时间:2014-01-08 17:41:32

标签: encryption private-key shared-secret

我正在尝试保护2048位RSA私钥(机密性和可用性)。 我一直在寻找有关如何做到这一点的更多信息,我正在考虑使用秘密共享方案(Shamir的秘密共享会很好)。

这是最好的选择吗? 有没有人知道GNU / GPL软件的实现才能实现这个目标?

我查看“ssss”(http://point-at-infinity.org/ssss/),但秘密需要最多128个ASCII字符,并且对于2048位RSA私钥来说太短了。

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

与公钥加密一样,当数据超过一定大小时,您偶尔需要使用混合方案 - 您可以使用带有随机密钥的常规对称算法加密私钥,然后使用分割对称密钥一种选择的秘密分裂算法。

我相信这里的实现:https://github.com/moserware/SecretSplitter使用此方法来分割超出底层分割算法大小限制的数据。

答案 1 :(得分:0)

  

这是最好的选择吗?有没有人知道GNU / GPL软件的实现才能实现这个目标?

Crypto ++提供了这项功能。但许可证是Public Domain(个别源文件)或Boost Software 1.0(整个库)。它不是GNU / GPL。

以下是使用Crypto ++执行此操作的代码。它取自test.cpp

<强>分裂

void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
{
    RandomPool rng;
    rng.IncorporateEntropy((byte *)seed, strlen(seed));

    ChannelSwitch *channelSwitch;
    FileSource source(filename, false, new SecretSharing(rng,
        threshold, nShares, channelSwitch = new ChannelSwitch));

    vector_member_ptrs<FileSink> fileSinks(nShares);
    string channel;
    for (int i=0; i<nShares; i++)
    {
        char extension[5] = ".000";
        extension[1]='0'+byte(i/100);
        extension[2]='0'+byte((i/10)%10);
        extension[3]='0'+byte(i%10);
        fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));

        channel = WordToString<word32>(i);
        fileSinks[i]->Put((byte *)channel.data(), 4);
        channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
    }

    source.PumpAll();
}

<强>结合

void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
{
    SecretRecovery recovery(threshold, new FileSink(outFilename));

    vector_member_ptrs<FileSource> fileSources(threshold);
    SecByteBlock channel(4);
    int i;
    for (i=0; i<threshold; i++)
    {
        fileSources[i].reset(new FileSource(inFilenames[i], false));
        fileSources[i]->Pump(4);
        fileSources[i]->Get(channel, 4);
        fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
    }

    while (fileSources[0]->Pump(256))
        for (i=1; i<threshold; i++)
            fileSources[i]->Pump(256);

    for (i=0; i<threshold; i++)
        fileSources[i]->PumpAll();
}