有一个关键类:
public class EncryptKey
{
public EncryptKey (byte[] key) => Key = key;
public EncryptKey (string key) => FromString(key);
public byte[] Key { get; set; }
public void FromString (string s)
{
using SymmetricAlgorithm sa = Aes.Create();
using Rfc2898DeriveBytes hasher = new(s, sa.IV, 5000, HashAlgorithmName.SHA512);
Key = hasher.GetBytes(32);
}
public override string ToString() => Convert.ToBase64String(Key);
}
加密实现如下所示:
public static string Encrypt (string text, IEncryptKey key)
{
string textToEncode = text.Replace("/", "%SL%").Replace("+", "%PL%");
using Aes aes = Aes.Create();
aes.Key = key.Key;
using MemoryStream ms = new();
ms.Write(aes.IV);
using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true))
cs.Write(Encoding.UTF8.GetBytes(textToEncode));
return Convert.ToBase64String(ms.ToArray());
}
public static string Decrypt (string text, IEncryptKey key)
{
string textToDecode = text.Replace("%SL%", "/").Replace("%PL%", "+");
using MemoryStream ms = new(Convert.FromBase64String(textToDecode));
byte[] iv = new byte[16];
_ = ms.Read(iv);
using Aes aes = Aes.Create();
aes.Key = key.Key;
aes.IV = iv;
using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true);
using MemoryStream output = new();
cs.CopyTo(output);
return Encoding.UTF8.GetString(output.ToArray());
}
我这样称呼:
var encText = Encrypt(Guid.NewGuid().ToString, new("123"));
var decText = Decrypt(encText, new("123"));
结果,出现错误:
FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters
对密码进行哈希处理时,IV 不应随意使用,而应使用相同的值。也就是说,加密时使用哪个IV,解密时也应该使用相同的IV。
嗯,他们在课程上很聪明,此外,将密钥永久存储在内存中对于安全来说是一个坏兆头。5000 次迭代 - 剥夺不会增加可靠性的工作。对 256 位密钥使用 512 位哈希值也不好。
凡事适度就好。即使知道盐的人也无法对密码进行哈希处理,即使经过哈希处理、重新哈希 1000 次甚至更多次。阅读RFC 2898。
如果需要Base64 URL格式,那么可以按照标准进行转换
尽量不要在一种方法中混合多种不同类型的问题。该方法必须做一件事。
输出到控制台(每次输出不同的base64,但应该是这样)
现在,当它工作时,您已经可以在其上包装抽象、类和其他 OOP。祝你好运!