PKCS#11将私钥解包到HSM

时间:2018-12-12 14:17:10

标签: pkcs#11 pkcs11interop

我了解到我不能简单地通过PKCS#11将私钥转移到我的HSM,我需要先包装它,然后再将其解包到HSM上。因此,我暂时在我们的HSM上创建了一个DES3密钥,然后我想用它包装(加密)我的RSA私钥,然后我想在HSM上解开它。

我的代码如下:

    // Create temporary DES3 key for wrapping/unwrapping
    var tempKeyAttributes = new List<ObjectAttribute>();
    tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
    tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
    tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
    tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));
    var tempKey = session.GenerateKey(new Mechanism(CKM.CKM_DES3_KEY_GEN), tempKeyAttributes);

    // Encrypt (wrap) the RSA private key
    var encryptedPrivateKeyParamsD = session.Encrypt(new Mechanism(CKM.CKM_DES3_ECB), tempKey, privateKeyParams.D);

    // Define how the new RSA private key should look like on the HSM
    var privateKeyAttributes = new List<ObjectAttribute>();
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
    [...]

    // Unwrap the private key onto the HSM
    var privateKeyHandle = session.UnwrapKey(new Mechanism(CKM.CKM_DES3_ECB), tempKey, encryptedPrivateKeyParamsD, privateKeyAttributes);

这不起作用,它失败,并显示CKR_INVALID_MECHANISM

我很确定问题是encryptedPrivateKeyParamsD,我应该以某种方式加密整个密钥。但是如何?正确的格式是什么?我在文档中找不到任何有关它的内容:-(

有什么办法解决此问题吗?我只想使用PKCS#11以编程方式将现有的RSA私钥放到我们的HSM中。

1 个答案:

答案 0 :(得分:1)

我找到了答案:在SafeNet Luna HSM上必须使用的格式是二进制DER编码的PKCS#8。我使用BouncyCastle将输入数据转换为正确的格式:

var unencryptedPrivateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
        new RsaPrivateCrtKeyParameters(
            new BigInteger(1, privateKeyParams.Modulus),
            new BigInteger(1, privateKeyParams.Exponent),
            new BigInteger(1, privateKeyParams.D),
            new BigInteger(1, privateKeyParams.P),
            new BigInteger(1, privateKeyParams.Q),
            new BigInteger(1, privateKeyParams.DP),
            new BigInteger(1, privateKeyParams.DQ),
            new BigInteger(1, privateKeyParams.InverseQ))).GetEncoded();

var result = new MemoryStream();
session.Encrypt(new Mechanism(CKM.CKM_DES3_CBC_PAD, iv), tempKey, new MemoryStream(unencryptedPrivateKey), result);
var encryptedPrivateKey = result.ToArray();

[...]

var privateKeyHandle = session.UnwrapKey(new Mechanism(CKM.CKM_DES3_CBC_PAD, iv), tempKey, encryptedPrivateKey, privateKeyAttributes);