本文介绍了NsisCrypt在获取Windows CryptoAPI上下文时返回“错误”在所有的开发机器上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在尝试使用 NsisCrypt plugin 在编写密码之前加密一些密码到配置文件。 我的安装程序脚本中有以下代码: StrCpy $ algorithm3des NsisCrypt :: Base64Encode< key string> Pop $ key NsisCrypt :: Base64Encode< iv string> Pop $ iv NsisCrypt :: EncryptSymmetric $ teststring $ algorithm $ key $ iv Pop $ encryptedString 这在我的开发机器上工作正常。字符串被加密,当我在程序中调用以下代码时,返回正确的明文字符串: private string DecryptInternal(string source,string key,string iv) { byte [] resultArray = null; 使用(var prov3des = new TripleDESCryptoServiceProvider()) { prov3des.Key = Encoding.UTF8.GetBytes(key); prov3des.Mode = CipherMode.CBC; prov3des.Padding = PaddingMode.PKCS7; prov3des.IV = Encoding.UTF8.GetBytes(iv); 使用(var cTransform = prov3des.CreateDecryptor()) { byte [] stringToDecrypt = Convert.FromBase64String(source); resultArray = cTransform.TransformFinalBlock(stringToDecrypt,0,stringToDecrypt.Length); } } 返回Encoding.UTF8.GetString(resultArray); } 但是,当我在任何其他机器上运行安装程序时,我得到以下写进入配置文件: NSIS插件页面在 EncryptSymmetric 方法的描述中具有以下内容:所以我的开发机器规格是: ul> 安装了Windows 4.0的Windows 7 Enterprise 64位 我看到的机器失败是: Windows 7 Enterprise 64位与.NET 4 Extended安装 Windows Vista Enterprise 32位与.NET 4扩展安装 安装了Windows 4扩展版的Windows XP 32位 有关我做错什么的线索? 在运行Anders提供的代码之后,我可以看到返回的错误代码是根据这个页面是 NTE_BAD_KEYSET 0x80090016L 无法打开密钥容器。这个错误的常见原因是密钥容器不存在。要创建密钥容器,请使用CRYPT_NEWKEYSET标志调用CryptAcquireContext。此错误代码还可以指示对现有密钥容器的访问被拒绝。密钥集创建者可以使用CryptSetProvParam授予对容器的访问权限。 所以我只需要确定是否到期关键容器不存在(不太可能会想到)或由于访问被拒绝(更有可能我认为)。解决方案 Anders提供的信息显示,我的问题与其他NsisCrypt错误报告。我实现了这个修复程序,密码被正确加密。代码只是这样做: if(!CryptAcquireContext(& hProv,NULL,MS_ENHANCED_PROV,PROV_RSA_FULL,0)) { pushstring(获取Windows CryptoAPI上下文时出错); return; } 应该这样做: $ b $如果(!CryptAcquireContext(& hProv,NULL,MS_ENHANCED_PROV,PROV_RSA_FULL,0)) { if(GetLastError()== NTE_BAD_KEYSET) { //找不到默认容器。尝试创建它。 if(!CryptAcquireContext(& hProv,NULL,MS_ENHANCED_PROV,PROV_RSA_FULL,CRYPT_NEWKEYSET)) { pushstring(无法为Windows CryptoAPI上下文创建密钥); return; } } else { pushstring(获取Windows CryptoAPI上下文时出错); return; } } 这是在几个地方,所以需要重构自己的方法。 所以,直到新版本的NsisCrypt被发布,我们不得不拿一个源(NsisCrypt.cpp)的副本,并修改它使用此修复程序调用三个位置 CryptAcquireContext 。这些是 哈希 加密对称 DecrypySymmetric 我们没有修改 加密对等 解密不对称 因为我们没有使用这些方法。 $ bI'm trying to use the NsisCrypt plugin to encrypt a couple of passwords before writing them to a config file.I have the following code in my installer script:StrCpy $algorithm "3des"NsisCrypt::Base64Encode "<key string>"Pop $keyNsisCrypt::Base64Encode "<iv string>"Pop $ivNsisCrypt::EncryptSymmetric $teststring $algorithm $key $ivPop $encryptedStringThis works fine on my development machine. The string is encrypted and when I call the following code in my program the correct clear text string is returned:private string DecryptInternal(string source, string key, string iv){ byte[] resultArray = null; using (var prov3des = new TripleDESCryptoServiceProvider()) { prov3des.Key = Encoding.UTF8.GetBytes(key); prov3des.Mode = CipherMode.CBC; prov3des.Padding = PaddingMode.PKCS7; prov3des.IV = Encoding.UTF8.GetBytes(iv); using (var cTransform = prov3des.CreateDecryptor()) { byte[] stringToDecrypt = Convert.FromBase64String(source); resultArray = cTransform.TransformFinalBlock(stringToDecrypt, 0, stringToDecrypt.Length); } } return Encoding.UTF8.GetString(resultArray);}However, when I run the installer on any other machine I get the following written into the config file:The NSIS plugin page has the following in the description of the EncryptSymmetric method:So why am I getting this error on some machines, but not my development machine.My development machine specs are:Windows 7 Enterprise 64 bit with .NET 4.0 installedThe machines where I'm seeing the failure are:Windows 7 Enterprise 64 bit with .NET 4 Extended installedWindows Vista Enterprise 32 bit with .NET 4 Extended installedWindows XP 32 bit with .NET 4 Extended installedAny clues about what I'm doing wrong?Right - after running the code provided by Anders I can see that the error code being returned isWhich according to this page isSo I just need to find out whether it's due to the key container not existing (unlikely I would have thought) or due to access being denied (more likely I think). 解决方案 The information provided by Anders showed that my problem was the same as in the other NsisCrypt bug report. I implemented that fix and the passwords were encrypted correctly. Where the code just does this:if (!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0)){ pushstring("Error while acquiring Windows CryptoAPI context"); return;}It should do this:if (!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0)){ if (GetLastError() == NTE_BAD_KEYSET) { // No default container was found. Attempt to create it. if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { pushstring("Could not create key for Windows CryptoAPI context"); return; } } else { pushstring("Error while acquiring Windows CryptoAPI context"); return; }}This is in several places so will need to be refactored into its own method.So, until a new version of NsisCrypt is released we've had to take a copy of the source (NsisCrypt.cpp) and modify it in the three places where CryptAcquireContext is called with this fix. These areHashEncryptSymmetricDecrypySymmetricWe didn't modifyEncryptAsymmetricDecryptAsymmetricas we're not using those methods. 这篇关于NsisCrypt在获取Windows CryptoAPI上下文时返回“错误”在所有的开发机器上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-13 13:30