Equivalent of Data Protection API on Linux
Microsoft Windows 2000 and later versions expose the Data Protection API (DPAPI) that encrypts data for a per-user or per-system context. The caller does not provide a key with which to encrypt the data. Rather, the data is encrypted with a key derived from the user or system credentials.
This API is conveniently exposed in .NET via the ProtectedData class:
// Encrypts the data in a specified byte array and returns a byte array
// that contains the encrypted data.
public static byte[] Protect(
byte[] userData,
byte[] optionalEntropy,
DataProtectionScope scope
)
// Decrypts the data in a specified byte array and returns a byte array
// that conta开发者_高级运维ins the decrypted data.
public static byte[] Unprotect(
byte[] encryptedData,
byte[] optionalEntropy,
DataProtectionScope scope
)
Is there an equivalent API on Linux? A bonus would be that it integrates conveniently with Java.
What are my alternatives if there isn't one?
There are two options for user-level key stores on Linux:
- GnomeKeyring
- KWallet
This does not address the need for a system-level key store.
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-5.0
Here!
This documentation is so good, that I won't even bother to explain more. Do not be discouraged with no immediate code samples on the first page. There are examples in links there. For all scenarios. DI, ASP.NET, console. Windows and Linux.
As the others before me said - AFAIK you don't have default keys for users and system in Linux. But a key is a key. You can create them and on Linux it's your (as the administrator / root) responsibility to protect the key files (meaning make them accessible only to authorized users).
The good part is you do not rely on system specific keys. You just use separate keys, your application keys.
If that is what you need - the linked API is just for you. I wish Linux had built in, default keys for users, but well... It's just one extra step for increased app-level security. Do you want one step more? Use Azure Key Vault, they have nice REST API you can use anywhere, not necessarily in Dotnet. Yes, AKV requires locally stored user password, but you can disable the access remotely, so it's a good additional security layer. If your user / machine was compromised, you just disable the secret and the target app is disabled until you provide the user with the new key. I use it in my sensitive apps a lot. Works as charm.
BTW, my minimalistic example of Linux DPAPI usage:
using System;
using System.IO;
using Microsoft.AspNetCore.DataProtection;
var keyDirectory = Directory.GetCurrentDirectory();
var dataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(keyDirectory));
var protector = dataProtectionProvider.CreateProtector("Test");
var password = "Secret1337";
var protectedPassword = protector.Protect(password);
Console.WriteLine($"Protected: {protectedPassword}");
var decodedPassword = protector.Unprotect(protectedPassword);
Console.WriteLine($"Decoded: {decodedPassword}");
Of course in real world app you won't store keys in current directory, but that's the simplest example I could think of.
It doesn't look any more (or less) advanced than PGP, or Pretty Good Privacy. There are APIs available for PGP, and the one that I recall others speaking kindly of is Bouncy Castle.
Here's an example of how someone used Bouncy Castle.
Better APIs or solutions may be available, depending on your specific needs.
DPAPI does not exist on Linux.
Windows uses a special machine-id to deviate a machine key. You can emulate this behavior by looking into "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid" reading this key and deviate your special key by using any encryption library you want.
Under Linux on the other hand this machine-id is stored in the file "/etc/machine-id". You can read it's contents and deviate your special key from it. Be aware this key may be the same when using fast deployment VMs.
Encrypt your data with this special machine-id and it cannot not be read across other machines. Read at first the machine-id (Linux or Windows) and then try to decrypt the contents of your data. On another machine the result will obviously be different and not correct.
You can code your platform independent wrapper class by using the information from above.
Hope this helps someone in the future.
Cheers
精彩评论