gpt4 book ai didi

c# - 使用 MachineKey 的加密不是持久的

转载 作者:太空狗 更新时间:2023-10-30 00:19:05 27 4
gpt4 key购买 nike

我使用 MachineKey.Protect() 方法来加密在我的 asp.net MVC 应用程序中作为查询字符串传递的 id。

这是我用来加密/解密的代码:

public static string Encrypt(this string expression)
{
if (string.IsNullOrEmpty(expression))
return string.Empty;

byte[] stream = Encoding.Unicode.GetBytes(expression);
byte[] encodedValue = MachineKey.Protect(stream);
return HttpServerUtility.UrlTokenEncode(encodedValue);
}

public static string Decrypt(this string expression)
{
if (string.IsNullOrEmpty(expression))
return string.Empty;

byte[] stream = HttpServerUtility.UrlTokenDecode(expression);
byte[] decodedValue = MachineKey.Unprotect(stream);
return Encoding.Unicode.GetString(decodedValue);
}

而且,这是我的 web.config 文件中的 MachineKey 元素:

<system.web>
.
.
.
<machineKey validationKey="xxx" decryptionKey="xxx" validation="SHA1" decryption="AES" />
</system.web>

问题是加密的 id 不是持久的。每次我调用该方法时,我都会得到一个新的加密表达式。如何让它持久化?

最佳答案

总结:

如果你想每次都得到相同的结果,你需要使用不同的方法来保护你的数据。 MachineKey.Protect 每次运行都使用不同的 IV,每次都会产生不同的结果。

详情

Microsoft 使许多 dot net 框架的源代码可以在 Internet 上免费查看。

从顶部开始:MachineKey

保护方法使用 AspNetCryptoServiceProvider

如果按照代码通过AspNetCryptoServiceProvider.GetCryptoService进入NetFXCryptoService ,你会发现这个:

public byte[] Protect(byte[] clearData) {
// The entire operation is wrapped in a 'checked' block because any overflows should be treated as failures.
checked {

// These SymmetricAlgorithm instances are single-use; we wrap it in a 'using' block.
using (SymmetricAlgorithm encryptionAlgorithm = _cryptoAlgorithmFactory.GetEncryptionAlgorithm()) {
// Initialize the algorithm with the specified key and an appropriate IV
encryptionAlgorithm.Key = _encryptionKey.GetKeyMaterial();

if (_predictableIV) {
// The caller wanted the output to be predictable (e.g. for caching), so we'll create an
// appropriate IV directly from the input buffer. The IV length is equal to the block size.
encryptionAlgorithm.IV = CryptoUtil.CreatePredictableIV(clearData, encryptionAlgorithm.BlockSize);
}
else {
// If the caller didn't ask for a predictable IV, just let the algorithm itself choose one.
encryptionAlgorithm.GenerateIV();
}
byte[] iv = encryptionAlgorithm.IV;

using (MemoryStream memStream = new MemoryStream()) {
memStream.Write(iv, 0, iv.Length);

// At this point:
// memStream := IV

// Write the encrypted payload to the memory stream.
using (ICryptoTransform encryptor = encryptionAlgorithm.CreateEncryptor()) {
using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write)) {
cryptoStream.Write(clearData, 0, clearData.Length);
cryptoStream.FlushFinalBlock();

// At this point:
// memStream := IV || Enc(Kenc, IV, clearData)

// These KeyedHashAlgorithm instances are single-use; we wrap it in a 'using' block.
using (KeyedHashAlgorithm signingAlgorithm = _cryptoAlgorithmFactory.GetValidationAlgorithm()) {
// Initialize the algorithm with the specified key
signingAlgorithm.Key = _validationKey.GetKeyMaterial();

// Compute the signature
byte[] signature = signingAlgorithm.ComputeHash(memStream.GetBuffer(), 0, (int)memStream.Length);

// At this point:
// memStream := IV || Enc(Kenc, IV, clearData)
// signature := Sign(Kval, IV || Enc(Kenc, IV, clearData))

// Append the signature to the encrypted payload
memStream.Write(signature, 0, signature.Length);

// At this point:
// memStream := IV || Enc(Kenc, IV, clearData) || Sign(Kval, IV || Enc(Kenc, IV, clearData))

// Algorithm complete
byte[] protectedData = memStream.ToArray();
return protectedData;
}
}
}
}
}
}
}

该类是使用默认选项初始化的,因此 _predictableIV 为 false。

因此,它每次都使用一个新的 IV,这意味着每次的结果都会不同,即使输入相同也是如此。

IV 包含在结果中,因此 Unprotect 方法可以反转加密。

关于c# - 使用 MachineKey 的加密不是持久的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25206248/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com