【发布时间】:2022-04-04 02:27:26
【问题描述】:
出于某种原因,我被要求实施一些基本加密来保护传输到客户端的特定值(取决于客户端)。
上下文是:我们是生成加密密钥的人,我们将该加密密钥传递给客户端,客户端永远不必解密它(但我们必须在后端)
示例 => 我们将加密密钥“123ABCDE==”提供给客户端。客户端调用我们的 API 传递数据 + 加密密钥,例如:
{
"encKey": "123ABCDE==",
"payload": "somedatahere"
}
然后我们解密密钥,如果它与 DB 中的特定值匹配(同样,取决于客户端),我们继续进行一些其他操作。
所以,我决定使用 AES 加密。以下是我现在所拥有的。
关键信息的定义:
public class KeyInfo
{
public byte[] Key { get; }
public byte[] Iv { get; }
public KeyInfo()
{
using (var myAes = Aes.Create())
{
Key = myAes.Key;
Iv = myAes.IV;
}
}
public KeyInfo(string key, string iv)
{
Key = Convert.FromBase64String(key);
Iv = Convert.FromBase64String(iv);
}
}
加密方式
private static byte[] Encrypt_AES(string plainText, byte[] key, byte[] iv)
{
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException(nameof(plainText));
if (key == null || key.Length <= 0)
throw new ArgumentNullException(nameof(key));
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException(nameof(iv));
byte[] encrypted;
using (var aesAlgo = Aes.Create())
{
aesAlgo.Key = key;
aesAlgo.IV = iv;
var encryptor = aesAlgo.CreateEncryptor(aesAlgo.Key, aesAlgo.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
解密方法:
private static string Decrypt_AES(byte[] cipherText, byte[] key, byte[] iv)
{
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException(nameof(cipherText));
if (key == null || key.Length <= 0)
throw new ArgumentNullException(nameof(key));
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException(nameof(iv));
string plaintext;
using (var aesAlgo = Aes.Create())
{
aesAlgo.Key = key;
aesAlgo.IV = iv;
var decryptor = aesAlgo.CreateDecryptor(aesAlgo.Key, aesAlgo.IV);
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
存储在 appsettings.json 中的密钥和 IV:
"EncryptionKey": "myEncryptionKeyHere",
"EncryptionInitialVector": "myInitialVectorHere",
在 Satrtup.cs 中的注册
services.AddTransient(ec => new EncryptionService(new KeyInfo(appSettings.EncryptionKey, appSettings.EncryptionInitialVector)));
关于这一切我有几个问题。
- AES rh 是否适合我的需求?
- 这里的实现方式是否正确?
- 我应该将密钥和 IV 存储在哪里? (不确定 appsettings.json 是否正常)
- 如何生成密钥和 IV?有相应的工具吗?
感谢阅读!
编辑:
您说“我们是生成加密密钥的人,我们通过 给客户端的加密密钥”——这是如何安全地进行的?
-> 客户必须连接到他的帐户才能访问encKey。
所以,阅读@vcsjones 的答案,AES 可能不是在这里实施的正确方法。由于我不想将 IV 存储在数据库中,如果客户端丢失它,这意味着他必须使用另一个 IV 生成另一个密钥,并在所有应用程序中更改 encKey。
非对称加密会更好吗?如果我理解正确,这意味着使用私钥加密值,将该加密值提供给客户端 + 公钥(每个客户端都相同?)
【问题讨论】:
标签: security asp.net-core encryption aes