我有一个使用Process.Start()
执行可执行文件的程序。我调用的可执行文件是更新ProgramData
中的文件夹的第三方程序。一旦ProgramData
中的文件夹得到更新,程序中的下一行就会尝试阅读最新的更改。
我注意到即使在执行可执行文件后也无法读取最新的更改,但是当我从头开始重新运行程序时,我可以看到正确读取的更改。我假设这与AppDomain
无法在执行期间看到更改有关。
无论如何我能在这里工作吗?
在方法HSMTransactionHandler
内的下面的代码中,如果发生消息HSM_ENCRYPTION_KEY_NOT_FOUND
的异常,那么我通过调用方法UpdateFromRFS
执行exe,然后递归调用HSMTransactionHandler
。 exe的执行获取所需的资源,但代码不读取它。如果我在执行当前程序期间运行另一个程序,则第二个程序会毫无问题地读取资源。这让我想到一个进程或应用程序域是否可以看到ProgramData
文件夹启动后发生的更改?
这样每个人都知道我正在使用PKCS11Interop
库,这是一个围绕本机dll构建的托管.net
包装器。我也不确定使用本机dll是否会导致这种情况。
任何帮助都将受到高度赞赏。
以下是代码:
public sealed class KeyStoreOperations
{
private KeyStoreContext m_keyStoreContext;
private static Pkcs11 m_Pkcs11;
private static readonly object _syncLockPkcs11 = new object();
private static readonly object _syncLockHSMLogin = new object();
public KeyStoreOperations(KeyStoreContext keyStoreContext)
{
m_keyStoreContext = keyStoreContext;
InitializePkcs11Object();
}
public string Encrypt(string keyName, string message)
{
ValidateInputs(message, "Message");
var encryptedMessage = string.Empty;
HSMTransactionHandler((Session session) =>
{
Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS);
var publicKey = GetPublicKey(keyName, session);
if (publicKey == null)
throw new HSMException(ErrorConstant.HSM_ENCRYPTION_KEY_NOT_FOUND);
var originalKeyBytes = EncryptionHelper.Decode(message);
var encryptedKeyBytes = session.Encrypt(mechanism, publicKey, originalKeyBytes);
encryptedMessage = EncryptionHelper.Encode(encryptedKeyBytes);
});
return encryptedMessage;
}
public string Decrypt(string keyName, string cipher)
{
ValidateInputs(cipher, "Cipher");
var decryptedMessage = string.Empty;
HSMTransactionHandler((Session session) =>
{
Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS);
var privateKey = GetPrivateKey(keyName, session);
if (privateKey == null)
throw new HSMException(ErrorConstant.HSM_ENCRYPTION_KEY_NOT_FOUND);
var encryptedSymmetricKeyBytes = EncryptionHelper.Decode(cipher);
var decryptedSymmetricKeyBytes = session.Decrypt(mechanism, privateKey, encryptedSymmetricKeyBytes);
decryptedMessage = EncryptionHelper.Encode(decryptedSymmetricKeyBytes);
});
return decryptedMessage;
}
#region Private methods
#region Validations
private void ValidateInputs(string input, string name)
{
if (string.IsNullOrEmpty(input))
throw new ArgumentNullException(name);
}
#endregion Validations
private void HSMTransactionHandler(Action<Session> action, bool commit = false, int retrialAttempt = 5)
{
Slot hsmSlot = null;
Session hsmSession = null;
bool logggedIn = false;
try
{
hsmSlot = GetSlot(m_NCipherKeyStoreContext.ModuleToken);
hsmSession = hsmSlot.OpenSession(false);
lock (_syncLockHSMLogin)
{
hsmSession.Login(CKU.CKU_USER, m_NCipherKeyStoreContext.SecurityPin);
logggedIn = true;
action(hsmSession);
hsmSession.Logout();
logggedIn = false;
}
if (commit)
CommitToRFS();
}
catch (Pkcs11Exception ex)
{
HandleHSMErrors(ex);
}
catch (HSMException ex)
{
if (ex.Message == EncryptionKeyStoreErrorConstant.HSM_ENCRYPTION_KEY_NOT_FOUND && retrialAttempt > 0)
{
if (logggedIn)
{
hsmSession.Logout();
logggedIn = false;
}
if (!(hsmSession == null))
hsmSession.CloseSession();
UpdateFromRFS();
Thread.Sleep(1000);
HSMTransactionHandler(action, retrialAttempt: retrialAttempt - 1);
}
else
throw ex;
}
finally
{
if (logggedIn)
hsmSession.Logout();
if (!(hsmSession == null))
hsmSession.CloseSession();
}
}
private void UpdateFromRFS()
{
using (var rfsSyncProcess = GetRfsSyncProcess("--update"))
{
ExecuteRFSSyncProcess(rfsSyncProcess);
}
}
private Process GetRfsSyncProcess(string args)
{
Process rfsSyncProcess = new Process();
rfsSyncProcess.StartInfo.FileName = "C:\\Program Files (x86)\\nCipher\\nfast\\bin\\rfs-sync.exe";
rfsSyncProcess.StartInfo.Arguments = args;
return rfsSyncProcess;
}
private void ExecuteRFSSyncProcess(Process rfsSyncProcess)
{
rfsSyncProcess.Start();
rfsSyncProcess.WaitForExit();
}
private ObjectHandle GetPrivateKey(string keyName, Session session)
{
ObjectHandle privateKey = null;
List<ObjectHandle> foundObjects = null;
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
foundObjects = session.FindAllObjects(objectAttributes);
if (foundObjects != null && foundObjects.Count > 0)
{
privateKey = foundObjects[0];
}
return privateKey;
}
private ObjectHandle GetPublicKey(string keyName, Session session)
{
ObjectHandle publicKey = null;
List<ObjectHandle> foundObjects = null;
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
foundObjects = session.FindAllObjects(objectAttributes);
if (foundObjects != null && foundObjects.Count > 0)
{
publicKey = foundObjects[0];
}
return publicKey;
}
private List<ObjectAttribute> CreatePublicKeyTemplate(string keyName, byte[] ckaId)
{
List<ObjectAttribute> publicKeyAttributes = new List<ObjectAttribute>();
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY_RECOVER, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_WRAP, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS_BITS, Convert.ToUInt64(m_keyStoreContext.KeySize)));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
return publicKeyAttributes;
}
private List<ObjectAttribute> CreatePrivateKeyTemplate(string keyName, byte[] ckaId)
{
List<ObjectAttribute> privateKeyAttributes = new List<ObjectAttribute>();
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN_RECOVER, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));
return privateKeyAttributes;
}
private Slot GetSlot(string tokenLabel)
{
Slot matchingSlot = null;
List<Slot> slots = m_Pkcs11.GetSlotList(true);
matchingSlot = slots[0];
if (tokenLabel != null)
{
matchingSlot = null;
foreach (Slot slot in slots)
{
TokenInfo tokenInfo = null;
try
{
tokenInfo = slot.GetTokenInfo();
}
catch (Pkcs11Exception ex)
{
if (ex.RV != CKR.CKR_TOKEN_NOT_RECOGNIZED && ex.RV != CKR.CKR_TOKEN_NOT_PRESENT)
throw;
}
if (tokenInfo == null)
continue;
if (!string.IsNullOrEmpty(m_keyStoreContext.ModuleToken))
if (0 != string.Compare(m_keyStoreContext.ModuleToken, tokenInfo.Label, StringComparison.Ordinal))
continue;
matchingSlot = slot;
break;
}
if (matchingSlot == null)
throw new HSMException(string.Format(ErrorConstant.HSM_CONFIGURATION_ERROR_INCORRECT_SLOT, tokenLabel));
}
return matchingSlot;
}
private void InitializePkcs11Object()
{
if (m_Pkcs11 == null)
{
lock (_syncLockPkcs11)
{
m_Pkcs11 = new Pkcs11(m_keyStoreContext.PKCS11LibraryPath, true);
}
}
}
private void HandleHSMErrors(Pkcs11Exception ex)
{
if (ex.RV == CKR.CKR_PIN_INCORRECT)
{
throw new HSMException(ErrorConstant.HSM_CONFIGURATION_ERROR_PIN_INCORRECT, ex);
}
else
{
throw new HSMException(ErrorConstant.HSM_CONFIGURATION_ERROR_GENERIC, ex);
}
}
#endregion
}
编辑1:
以下是修改后的代码,请注意,最重要的是在CKNFAST_ASSUME_SINGLE_PROCESS
文件中将变量cknfastrc
设置为0
public sealed class KeyStoreOperations
{
private KeyStoreContext m_keyStoreContext;
private static Pkcs11 m_Pkcs11;
private static readonly object _syncLockPkcs11 = new object();
private static readonly object _syncLockHSMLogin = new object();
public KeyStoreOperations(KeyStoreContext keyStoreContext)
{
m_keyStoreContext = keyStoreContext;
InitializePkcs11Object();
}
public string Encrypt(string keyName, string message)
{
ValidateInputs(message, "Message");
var encryptedMessage = string.Empty;
HSMTransactionHandler((Session session) =>
{
Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS);
var publicKey = GetPublicKey(keyName, session);
if (publicKey == null)
throw new HSMException(ErrorConstant.HSM_ENCRYPTION_KEY_NOT_FOUND);
var originalKeyBytes = EncryptionHelper.Decode(message);
var encryptedKeyBytes = session.Encrypt(mechanism, publicKey, originalKeyBytes);
encryptedMessage = EncryptionHelper.Encode(encryptedKeyBytes);
});
return encryptedMessage;
}
public string Decrypt(string keyName, string cipher)
{
ValidateInputs(cipher, "Cipher");
var decryptedMessage = string.Empty;
HSMTransactionHandler((Session session) =>
{
Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS);
var privateKey = GetPrivateKey(keyName, session);
if (privateKey == null)
throw new HSMException(ErrorConstant.HSM_ENCRYPTION_KEY_NOT_FOUND);
var encryptedSymmetricKeyBytes = EncryptionHelper.Decode(cipher);
var decryptedSymmetricKeyBytes = session.Decrypt(mechanism, privateKey, encryptedSymmetricKeyBytes);
decryptedMessage = EncryptionHelper.Encode(decryptedSymmetricKeyBytes);
});
return decryptedMessage;
}
#region Private methods
#region Validations
private void ValidateInputs(string input, string name)
{
if (string.IsNullOrEmpty(input))
throw new ArgumentNullException(name);
}
#endregion Validations
private void HSMTransactionHandler(Action<Session> action, bool commit = false, int retrialAttempt = 5)
{
Slot hsmSlot = null;
Session hsmSession = null;
bool logggedIn = false;
try
{
hsmSlot = GetSlot(m_NCipherKeyStoreContext.ModuleToken);
hsmSession = hsmSlot.OpenSession(false);
lock (_syncLockHSMLogin)
{
hsmSession.Login(CKU.CKU_USER, m_NCipherKeyStoreContext.SecurityPin);
logggedIn = true;
action(hsmSession);
hsmSession.Logout();
logggedIn = false;
}
if (commit)
CommitToRFS();
}
catch (Pkcs11Exception ex)
{
HandleHSMErrors(ex);
}
catch (HSMException ex)
{
if (ex.Message == EncryptionKeyStoreErrorConstant.HSM_ENCRYPTION_KEY_NOT_FOUND && retrialAttempt > 0)
{
if (logggedIn)
{
hsmSession.Logout();
logggedIn = false;
}
if (!(hsmSession == null))
{
hsmSession.CloseSession();
hsmSession = null;
}
UpdateFromRFS();
Thread.Sleep(1000);
if (!m_Pkcs11.Disposed)
{
m_Pkcs11.Dispose();
m_Pkcs11 = null;
}
HSMTransactionHandler(action, retrialAttempt: retrialAttempt - 1);
}
else
throw ex;
}
finally
{
if (logggedIn)
hsmSession.Logout();
if (!(hsmSession == null))
hsmSession.CloseSession();
}
}
private void UpdateFromRFS()
{
using (var rfsSyncProcess = GetRfsSyncProcess("--update"))
{
ExecuteRFSSyncProcess(rfsSyncProcess);
}
}
private Process GetRfsSyncProcess(string args)
{
Process rfsSyncProcess = new Process();
rfsSyncProcess.StartInfo.FileName = "C:\\Program Files (x86)\\nCipher\\nfast\\bin\\rfs-sync.exe";
rfsSyncProcess.StartInfo.Arguments = args;
return rfsSyncProcess;
}
private void ExecuteRFSSyncProcess(Process rfsSyncProcess)
{
rfsSyncProcess.Start();
rfsSyncProcess.WaitForExit();
}
private ObjectHandle GetPrivateKey(string keyName, Session session)
{
ObjectHandle privateKey = null;
List<ObjectHandle> foundObjects = null;
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
foundObjects = session.FindAllObjects(objectAttributes);
if (foundObjects != null && foundObjects.Count > 0)
{
privateKey = foundObjects[0];
}
return privateKey;
}
private ObjectHandle GetPublicKey(string keyName, Session session)
{
ObjectHandle publicKey = null;
List<ObjectHandle> foundObjects = null;
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
foundObjects = session.FindAllObjects(objectAttributes);
if (foundObjects != null && foundObjects.Count > 0)
{
publicKey = foundObjects[0];
}
return publicKey;
}
private List<ObjectAttribute> CreatePublicKeyTemplate(string keyName, byte[] ckaId)
{
List<ObjectAttribute> publicKeyAttributes = new List<ObjectAttribute>();
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY_RECOVER, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_WRAP, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS_BITS, Convert.ToUInt64(m_keyStoreContext.KeySize)));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
return publicKeyAttributes;
}
private List<ObjectAttribute> CreatePrivateKeyTemplate(string keyName, byte[] ckaId)
{
List<ObjectAttribute> privateKeyAttributes = new List<ObjectAttribute>();
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, keyName));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN_RECOVER, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));
return privateKeyAttributes;
}
private Slot GetSlot(string tokenLabel)
{
Slot matchingSlot = null;
List<Slot> slots = m_Pkcs11.GetSlotList(true);
matchingSlot = slots[0];
if (tokenLabel != null)
{
matchingSlot = null;
foreach (Slot slot in slots)
{
TokenInfo tokenInfo = null;
try
{
tokenInfo = slot.GetTokenInfo();
}
catch (Pkcs11Exception ex)
{
if (ex.RV != CKR.CKR_TOKEN_NOT_RECOGNIZED && ex.RV != CKR.CKR_TOKEN_NOT_PRESENT)
throw;
}
if (tokenInfo == null)
continue;
if (!string.IsNullOrEmpty(m_keyStoreContext.ModuleToken))
if (0 != string.Compare(m_keyStoreContext.ModuleToken, tokenInfo.Label, StringComparison.Ordinal))
continue;
matchingSlot = slot;
break;
}
if (matchingSlot == null)
throw new HSMException(string.Format(ErrorConstant.HSM_CONFIGURATION_ERROR_INCORRECT_SLOT, tokenLabel));
}
return matchingSlot;
}
private void InitializePkcs11Object()
{
if (m_Pkcs11 == null)
{
lock (_syncLockPkcs11)
{
m_Pkcs11 = new Pkcs11(m_keyStoreContext.PKCS11LibraryPath, true);
}
}
}
private void HandleHSMErrors(Pkcs11Exception ex)
{
if (ex.RV == CKR.CKR_PIN_INCORRECT)
{
throw new HSMException(ErrorConstant.HSM_CONFIGURATION_ERROR_PIN_INCORRECT, ex);
}
else
{
throw new HSMException(ErrorConstant.HSM_CONFIGURATION_ERROR_GENERIC, ex);
}
}
#endregion
}
编辑2:我检查过并发现它的工作情况甚至没有将CKNFAST_ASSUME_SINGLE_PROCESS
设置为0,所以可能只需要处理pkcs11对象并重新初始化它
答案 0 :(得分:1)
根据您之前的问题#1,#2和#3我猜测(因为您没有写它)您正在执行rfs-sync.exe
和您的PKCS#11库仍然没有看到刚刚同步的键。如果是这种情况,那么您需要查阅HSM用户指南并找到变量(类似于CKNFAST_FAKE_ACCELERATOR_LOGIN
),这使您的PKCS#11库在每次执行搜索操作时重新读取本地FS。如果没有该变量,PKCS#11库只会在初始化期间缓存本地FS的内容。
答案 1 :(得分:0)
Process.Start()
立即返回,即表示该进程有started。换句话说,这意味着该过程尚未完成。
通常,您应该有some sort of wait来完成该过程。
即Process.WaitForExit()
或使用Process.Exited
事件。