PKCS#11 将私钥解包到 HSM
PKCS#11 unwrap private key to HSM
我了解到我不能简单地通过 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。
我找到了答案:在 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);
我了解到我不能简单地通过 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。
我找到了答案:在 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);