ata*_*ati 4 c# asp.net encryption asp.net-mvc machinekey
我使用该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);
}
而且,这是MachineKey我web.config文件中的元素:
<system.web>
    .
    .
    .
    <machineKey validationKey="xxx" decryptionKey="xxx" validation="SHA1" decryption="AES" />
</system.web>
问题是加密的id不是持久的.每当我调用该方法时,我都会得到一个新的加密表达式.我如何让它持久?
摘要:
如果您希望每次都获得相同的结果,则需要使用其他方法来保护数据.MachineKey.Protect每次运行使用不同的IV,每次都会产生不同的结果.
详情
微软在互联网上可以自由查看许多点网框架的源代码.
从顶部开始:MachineKey
protect方法使用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方法可以反转加密.
| 归档时间: | 
 | 
| 查看次数: | 4652 次 | 
| 最近记录: |