我想在Windows PC上安全地存储明文密码.我目前正在使用DPAPI CryptProtectData
对其进行加密,然后将加密的blob存储在用户本地AppData中的文件中.
在Windows 7中,有Windows Vault,凭据管理器(控制面板\用户帐户和家庭安全\凭证管理器),用于存储各种登录类型的登录数据,包括"通用凭据".从表面上看,这似乎是程序存储凭据的正确位置.但是,我无法找到任何API.我在MSDN中读取了身份验证功能参考,但坦率地说它迷失了.
是否存在用于存储和检索程序凭据的Windows Vault API,如果可以,我在哪里可以找到文档?
有没有办法在Windows XP上使用Python的DPAPI(数据保护应用程序编程接口)?
如果有一个可以做到的话,我更愿意使用现有的模块.很遗憾,我无法找到Google或Stack Overflow的方法.
编辑:我已经采用了"dF"指向的示例代码,并将其调整为一个独立的库,可以在高级别使用,只需在用户模式下使用DPAPI进行加密和解密.只需调用返回加密字符串的dpapi.cryptData(text_to_encrypt)或返回纯文本的反向decryptData(encrypted_data_string).这是图书馆:
# DPAPI access library
# This file uses code originally created by Crusher Joe:
# http://article.gmane.org/gmane.comp.python.ctypes/420
#
from ctypes import *
from ctypes.wintypes import DWORD
LocalFree = windll.kernel32.LocalFree
memcpy = cdll.msvcrt.memcpy
CryptProtectData = windll.crypt32.CryptProtectData
CryptUnprotectData = windll.crypt32.CryptUnprotectData
CRYPTPROTECT_UI_FORBIDDEN = 0x01
extraEntropy = "cl;ad13 \0al;323kjd #(adl;k$#ajsd"
class DATA_BLOB(Structure):
_fields_ = [("cbData", DWORD), ("pbData", POINTER(c_char))]
def getData(blobOut):
cbData = int(blobOut.cbData)
pbData = blobOut.pbData
buffer = c_buffer(cbData)
memcpy(buffer, pbData, cbData)
LocalFree(pbData);
return buffer.raw
def Win32CryptProtectData(plainText, entropy):
bufferIn …
Run Code Online (Sandbox Code Playgroud) 采取哪条路线,哪些优点和缺点,哪个更安全..
1)生成AES密钥,用它加密数据,然后用RSA加密AES密钥,将加密数据和加密的AES密钥保存到文件,并将RSA密钥保存到KeyContainer.
2)或者使用DPAPI ProtectedData类加密数据并将其保存到文件中,然后将我使用的熵存储ProtectedData.Protect()
到某个地方......(也可以用RSA加密它,将RSA密钥对存储到KeyContainer和加密的熵到带有数据的文件?)
编辑:只是为了更多信息:我们需要保护我们的应用程序文件系统使用.因此,应用程序存储到我们希望对其进行加密的文件系统的任何文件.该文件很可能由同一应用程序或同一应用程序堆栈的另一个组件使用.
我正在使用DPAPI来存储XML数据.CryptProtectData之后的数据存储在文件中.在我的一个用例中,需要在任何用户登录工作站之前解密此数据.由于,我不能在此使用用户专用密钥,我在加密时设置标志"CRYPTPROTECT_LOCAL_MACHINE".熵键是静态文本.
Unprotect在所有场景中都有效,除非我在登录前调用它(没有用户登录).它的返回错误87(参数不正确).
我重新阅读了整个DPAPI文档,以了解如何生成密钥.但是,遗憾的是,这个特定的旗帜没有足够的信息.
CryptUnprotectData会在这种情况下工作吗?是否可以由在某个用户会话下运行的应用程序调用?任何帮助表示赞赏.
感谢:D
我正在使用ASP.NET核心数据保护系统使用应用程序A加密数据并使用应用程序B对其进行解密.
加密和解密在开发机器上运行时都有效,但是当应用程序B移动到生产机器时,它不再能够解密,因为IDataProtector.Unprotect方法会抛出异常:
System.InvalidOperationException:密钥环不包含有效的默认保护密钥.数据保护系统无法创建新密钥,因为禁用了密钥的自动生成.
这是我用于在应用程序B中配置解密的代码:
sKeysPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Keys");
services.AddDataProtection()
.SetApplicationName("My Application") // Application A sets this same name
.PersistKeysToFileSystem(new DirectoryInfo(sKeysPath))
.ProtectKeysWithCertificate("634D3F23...")
//.ProtectKeysWithCertificate(x509Certificate2) // I've tried using an X509 certificate parameter but it gives the same result as providing the thumbprint of the one in the certificate store
.DisableAutomaticKeyGeneration(); // Application A is the master key generator so do not generate keys
Run Code Online (Sandbox Code Playgroud)
生产计算机确实包含相同的Keys文件夹(包含.pfx和.xml文件)以及Windows证书库中安装的相同密钥.
据我了解,通过将证书文件提供给Data Protection系统,它应该可以在任何计算机上运行,而不是绑定到特定计算机或Windows用户.这个假设是不正确的还是我正在执行解密的方式有问题?
以下是一些更详细的日志消息:
2018-06-13 16:32:32.6750 | TRACE | Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector | 5 | Performing unprotect …
所以我试图使用DPAPI存储对称密钥.一切都很好,但是如何处理熵呢?这个回答的问题在这里真的没有提供足够的洞察力.这似乎是一个滑坡 - 我可以使用机器商店来存储熵,但是那么是什么阻止了某人也可以使用它?注意:我使用用户范围存储当前密钥.
所以我的问题是 - 使用DPAPI存储熵的最佳方法是什么?
我正在测试使用.net v4的System.Security.Cryptography.ProtectedData()和UnprotectData()方法与DataProtectionScope.LocalMachine范围的想法,以确保只能在一台机器上加密/解密文件.以下是我正在做的事情的一般概念......
//Encrypt
byte[] outBytes = ProtectedData.Protect(File.ReadAllBytes(fileIn), null, DataProtectionScope.LocalMachine);
File.WriteAllBytes(fileOut, outBytes);
//Decrypt
byte[] outBytes = ProtectedData.Unprotect(File.ReadAllBytes(fileIn), null, DataProtectionScope.LocalMachine);
File.WriteAllBytes(fileOut, outBytes);
Run Code Online (Sandbox Code Playgroud)
我已经完成了大量的测试,以确保我在执行此操作时获得预期的行为,并且它似乎完美地工作,因为同一台计算机上的任何用户都可以使用上面列出的方法调用来加密/解密文件.
我的问题是,如果有人制作磁盘映像或克隆(使用Acronis,Ghost等等)包含使用此机制加密的文件的系统,然后将该映像还原到其他计算机,会发生什么?(一个例子是IT部门预先加载单个系统,然后成为具有相同硬件配置的大量机器的基本映像).在不同的硬件上恢复的操作系统是否能够解密在"原始"系统上加密的文件?我的希望是,由于硬件不同,解密将失败,但如果在注册表或文件系统中存在加密所需的所有必要信息,则可能会有效.
显然,我可以为自己测试一下,但我现在并没有真正有资源这么做,并且一直在不停地搜索,看看那里的其他人是否已经知道答案.任何建议都非常感谢!
我正在使用以下代码尝试以编程方式允许NetworkService帐户访问密钥:
var RSA = new RSACryptoServiceProvider(
new CspParameters() {
KeyContainerName = "MyEncryptionKey",
Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore
});
RSA.CspKeyContainerInfo.CryptoKeySecurity.AddAccessRule(
new System.Security.AccessControl.CryptoKeyAccessRule(
new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null),
CryptoKeyRights.GenericAll,
AccessControlType.Allow
)
);
Run Code Online (Sandbox Code Playgroud)
此代码运行时没有错误,但对密钥容器的权限没有影响.
但是,使用命令行工具aspnet_regiis做同样的事情,完美地工作:
aspnet_regiis -pa "MyEncryptionKey" "NetworkService"
Run Code Online (Sandbox Code Playgroud)
我正在运行完全管理员权限 - 如果我没有运行这些权限,则抛出异常.我也是最初创建密钥的用户.
密钥容器始终具有以下访问规则:
S-1-5-18 -> LocalSystem
S-1-5-32-544 -> Administrators
S-1-5-5-0-135377 -> MyUser
Run Code Online (Sandbox Code Playgroud)
使用aspnet_regiis,SID,S-1-5-20将添加到此列表中.我无法从代码中影响它.
我已经尝试以字符串格式从sid创建安全标识符,以及使用SetAccessRule而不是AddAccessRule.
任何想法如何从代码实际影响此ACL列表?
在每个C#应用程序中可以找到哪些信息可用作加密的唯一盐,包括Web应用程序,Windows服务和wcf层?
我想创建一个库,允许使用(DPAPI)System.Security.Cryptography.ProtectedData.Protect()
和System.Security.Cryptography.ProtectedData.Unprotect()
方法轻松加密存储在配置文件中的敏感数据.
该库也将由我正在制作的单独应用程序使用,它可以加密和解密使用这些值的应用程序之外的配置值,允许更新配置文件而无需重新编译所有内容或需要访问原始源,尽管访问源应始终可用.
salt必须足够简单,以便在单独的应用程序中手动输入(例如,GUID很难识别).
System.Reflection.Assembly.GetEntryAssembly()
看起来很有希望,如果那是调用我正在制作的这个库的应用程序/服务的程序集,我可以在那里使用一些东西.首先想到的是"将加密数据存储在配置文件名中的盐...",但对于网站,配置文件始终是"web.config".
欢迎任何其他想法.
更新...
'GetExecutingAssembly()'...与'GetEntryAssembly()'有何不同?
我有一个用于打开和解密 Google Chrome cookie 的工作脚本,如下所示:
decrypted = win32crypt.CryptUnprotectData(enctypted_cookie_value, None, None, None, 0)
Run Code Online (Sandbox Code Playgroud)
似乎在更新 80 之后它不再是一个有效的解决方案。
根据这篇博客文章https://blog.nirsoft.net/2020/02/19/tools-update-new-encryption-chrome-chromium-version-80/似乎我需要对本地状态文件中的 encrypted_key 进行 CryptUnprotectData ,而不是使用解密密钥以某种方式解密cookie。
对于第一部分,我得到了我的 encrypted_key
path = r'%LocalAppData%\Google\Chrome\User Data\Local State'
path = os.path.expandvars(path)
with open(path, 'r') as file:
encrypted_key = json.loads(file.read())['os_crypt']['encrypted_key']
encrypted_key = bytearray(encrypted_key, 'utf-8')
Run Code Online (Sandbox Code Playgroud)
然后我试图解密它
解密密钥 = win32crypt.CryptUnprotectData(加密密钥,无,无,无,0)
并得到了例外:
pywintypes.error: (13, 'CryptProtectData', 'The data is invalid.')
Run Code Online (Sandbox Code Playgroud)
我不知道如何修复它
同样对于加密的第二部分,我似乎应该使用 pycryptodome,类似于以下代码段:
cipher = AES.new(encrypted_key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt(data)
Run Code Online (Sandbox Code Playgroud)
但我不知道我应该在哪里获得 nonce 值
有人可以解释一下,如何正确解密 Chrome cookie?
dpapi ×10
c# ×5
.net ×2
encryption ×2
python ×2
security ×2
winapi ×2
windows ×2
aes ×1
asp.net-core ×1
cookies ×1
credentials ×1
cryptography ×1
entropy ×1