RSA Encryption with non exportable key in HSM using C# / CSP
Asked Answered
P

1

8

I'm trying to encrypt a symetric key with a RSA (Exchange Key in CSP) in C# using this piece of code (the RSA key CSP50C8C7CD is not exportable, and it's in HSM):

CspParameters csp_dnet = new CspParameters(1, "HSM especific CSP");
csp_dnet.Flags = CspProviderFlags.UseNonExportableKey;
csp_dnet.KeyContainerName = "test";

RSACryptoServiceProvider rsa_dnet = new RSACryptoServiceProvider(csp_dnet);

// Create 3DES key
TripleDES tripleDES = new TripleDESCryptoServiceProvider();

// Encrypt 3DES with RSA
byte[] encryptedSessionKey = rsa_dnet.Encrypt(tripleDES.Key, false);

Seeing the CSP log, I note that the C# is trying to export the key to proceed with the operation. The CSP log below just showing the piece about rsa_dnet.Encrypt use:

LOG CSP

...

[12/12/2012 17:28:45] [3688] D [CryptExportKey]  Blob type: PRIVATEKEYBLOB

...

[12/12/2012 17:28:45] [3688] E [CryptExportKey]  Return: FALSE. An internal error occurred.

Windows SO is calling a CryptExportKey passing PRIVATEKEYBLOB means to export de private key.

LOG HSM

...
2012/12/12 17:44:02 [4DD18140] new key 'test/CSP50C8C7CD', t: 6, a: 0
2012/12/12 17:44:14 [4DC2A1C0] 'test' auth ok, 10.0.87.19
2012/12/12 17:44:17 [4DC2A1C0] 'test/CSP50C8C7CD' not exportable, conn: 9  --- ERROR

In HSM this log show that the Windows SO is trying to extract the private key (what means the ERRO because the key is non exportable).

When I use a exportable key CSP50C8C7CE in HSM, the log show that is everything all right:

LOG HSM

...

2012/12/12 17:47:46 [4DEF4040] 'test' auth ok, IP: 10.0.87.19
2012/12/12 17:47:46 [4DEF4040] export: 'test/CSP50C8C7CE', 1462
2012/12/12 17:47:46 [4DEF4040] export: 'test/CSP50C8C7CE', 1462
2012/12/12 17:47:46 [4DEF4040] delete 'test/CSP50C8C7CE'
2012/12/12 17:47:46 [4DEF4040] import obj 'test/CSP50C8C7CE', 00000004
2012/12/12 17:47:46 [4DEF4040] pk test/CSP50C8C7CE [1]
2012/12/12 17:47:46 [4DEF4040] import obj 'cf1c34c8be5d2fa8a4575c63dd903454', 00000003
2012/12/12 17:47:46 [4DEF4040] delete 'test/CSP50C8C7CE'
2012/12/12 17:47:46 [4DEF4040] import obj 'test/CSP50C8C7CE', 00000006
2012/12/12 17:47:47 [4DEF4040] export: 'cf1c34c8be5d2fa8a4575c63dd903454', 24
2012/12/12 17:47:47 [4DEF4040] delete 'cf1c34c8be5d2fa8a4575c63dd903454'

Note that this log show lot's of RSA key import/export operations (Reference:CSP50C8C7CE - Exportable key).

Question: The Encrypt function in library System.Cryptography needs the key must be always exportable? Or I make any mistake in my program? Any missed parameter perhaps?

Peseta answered 19/12, 2012 at 18:40 Comment(0)
F
4

You cannot use a non-exportable key in an HSM for encryption or decryption in memory. Since you try to make encryption in memory .NET is trying to fetch the private key into memory and it is prevented by HSM. On the other hand, you can have the handle of private key and send your "data to be encrypted/decrypted" to HSM. In other words you can tell HSM to cipher your data with the private key it contains by specifying its handle.

Your HSM should be providing you an API which implements PKCS11 standard and often written in C. You can extern methods from this unmanaged library and use them in C#. Here you can find a PKCS11 wrapper library written in C#.

Funches answered 19/12, 2012 at 21:23 Comment(1)
the idea is to use encryption on HSM and use CSP to do so. The purpose of the Code would not do encryption in memory. The HSM provides a CSP driver that implements the API specific for such microsoft. The function rsa_dnet.Encrypt (tripleDES.Key, false) should not be trying to extract the private key since the flag CspProviderFlags.UseNonExportableKey is enabled.Peseta

© 2022 - 2024 — McMap. All rights reserved.