Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
利用ASP.NET machineKey加密我自己的数据_.net_Asp.net_Security_Cryptography - Fatal编程技术网

利用ASP.NET machineKey加密我自己的数据

利用ASP.NET machineKey加密我自己的数据,.net,asp.net,security,cryptography,.net,Asp.net,Security,Cryptography,我想在ASP.NET MVC应用程序中加密一些数据,以防止用户篡改。我可以使用加密类进行实际的加密/解密,没有问题。主要的问题是找出加密密钥的存储位置并管理对它的更改 由于ASP.NET已经为各种事情(ViewData encryption等)维护了machineKey,我想知道是否有任何ASP.NET函数可以让我使用machineKey对自己的数据进行加密/解密?这样我就不必设计自己的密钥管理系统了。我想不必直接设计。我不记得这是从哪里来的,可能是Reflector和一些博客的组合 publi

我想在ASP.NET MVC应用程序中加密一些数据,以防止用户篡改。我可以使用加密类进行实际的加密/解密,没有问题。主要的问题是找出加密密钥的存储位置并管理对它的更改


由于ASP.NET已经为各种事情(ViewData encryption等)维护了machineKey,我想知道是否有任何ASP.NET函数可以让我使用machineKey对自己的数据进行加密/解密?这样我就不必设计自己的密钥管理系统了。

我想不必直接设计。我不记得这是从哪里来的,可能是Reflector和一些博客的组合

public abstract class MyAwesomeClass
{
    private static byte[] cryptKey;

    private static MachineKeySection machineKeyConfig =
        (MachineKeySection)ConfigurationManager
            .GetSection("system.web/machineKey");

    // ... snip ...

    static MyAwesomeClass()
    {
        string configKey;
        byte[] key;

        configKey = machineKeyConfig.DecryptionKey;
        if (configKey.Contains("AutoGenerate"))
        {
            throw new ConfigurationErrorsException(
                Resources.MyAwesomeClass_ExplicitAlgorithmRequired);
        }

        key = HexStringToByteArray(configKey);

        cryptKey = key;
    }

    // ... snip ...

    protected static byte[] Encrypt(byte[] inputBuffer)
    {
        SymmetricAlgorithm algorithm;
        byte[] outputBuffer;

        if (inputBuffer == null)
        {
            throw new ArgumentNullException("inputBuffer");
        }

        algorithm = GetCryptAlgorithm();

        using (var ms = new MemoryStream())
        {
            algorithm.GenerateIV();
            ms.Write(algorithm.IV, 0, algorithm.IV.Length);

            using (var cs = new CryptoStream(
                 ms, 
                 algorithm.CreateEncryptor(), 
                 CryptoStreamMode.Write))
            {
                cs.Write(inputBuffer, 0, inputBuffer.Length);
                cs.FlushFinalBlock();
            }

            outputBuffer = ms.ToArray();
        }

        return outputBuffer;
    }

    protected static byte[] Decrypt(string input)
    {
        SymmetricAlgorithm algorithm;
        byte[] inputBuffer, inputVectorBuffer, outputBuffer;

        if (input == null)
        {
            throw new ArgumentNullException("input");
        }

        algorithm = GetCryptAlgorithm();
        outputBuffer = null;

        try
        {
            inputBuffer = Convert.FromBase64String(input);

            inputVectorBuffer = new byte[algorithm.IV.Length];
            Array.Copy(
                 inputBuffer, 
                 inputVectorBuffer,
                 inputVectorBuffer.Length);
            algorithm.IV = inputVectorBuffer;

            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(
                    ms, 
                    algorithm.CreateDecryptor(), 
                    CryptoStreamMode.Write))
                {
                    cs.Write(
                        inputBuffer,
                        inputVectorBuffer.Length, 
                        inputBuffer.Length - inputVectorBuffer.Length);
                    cs.FlushFinalBlock();
                }

                outputBuffer = ms.ToArray();
            }
        }
        catch (FormatException e)
        {
            throw new CryptographicException(
                "The string could not be decoded.", e);
        }

        return outputBuffer;
    }

    // ... snip ...

    private static SymmetricAlgorithm GetCryptAlgorithm()
    {
        SymmetricAlgorithm algorithm;
        string algorithmName;

        algorithmName = machineKeyConfig.Decryption;
        if (algorithmName == "Auto")
        {
            throw new ConfigurationErrorsException(
                Resources.MyAwesomeClass_ExplicitAlgorithmRequired);
        }

        switch (algorithmName)
        {
            case "AES":
                algorithm = new RijndaelManaged();
                break;
            case "3DES":
                algorithm = new TripleDESCryptoServiceProvider();
                break;
            case "DES":
                algorithm = new DESCryptoServiceProvider();
                break;
            default:
                throw new ConfigurationErrorsException(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        Resources.MyAwesomeClass_UnrecognizedAlgorithmName,
                        algorithmName));
        }

        algorithm.Key = cryptKey;

        return algorithm;
    }

    private static byte[] HexStringToByteArray(string str)
    {
        byte[] buffer;

        if (str == null)
        {
            throw new ArgumentNullException("str");
        }

        if (str.Length % 2 == 1)
        {
            str = '0' + str;
        }

        buffer = new byte[str.Length / 2];

        for (int i = 0; i < buffer.Length; ++i)
        {
            buffer[i] = byte.Parse(
                str.Substring(i * 2, 2),
                NumberStyles.HexNumber,
                CultureInfo.InvariantCulture);
        }

        return buffer;
    }
}
公共抽象类MyAwesomeClass
{
私有静态字节[]密钥;
专用静态MachineKeySection machineKeyConfig=
(机器钥匙部分)配置经理
.GetSection(“system.web/machineKey”);
//…剪断。。。
静态MyAwesomeClass()
{
字符串配置键;
字节[]键;
configKey=machineKeyConfig.DecryptionKey;
if(configKey.Contains(“自动生成”))
{
抛出新的ConfigurationErrorsException(
资源。MyAwesomeClass(需要明确的算法);
}
key=HexStringToByteArray(configKey);
cryptKey=密钥;
}
//…剪断。。。
受保护的静态字节[]加密(字节[]inputBuffer)
{
对称算法;
字节[]输出缓冲区;
如果(inputBuffer==null)
{
抛出新ArgumentNullException(“inputBuffer”);
}
算法=GetCryptAlgorithm();
使用(var ms=new MemoryStream())
{
GenerateIV()算法;
ms.Write(算法IV,0,算法IV.Length);
使用(var cs=newcryptostream)(
太太
算法。CreateEncryptor(),
CryptoStreamMode.Write)
{
cs.Write(inputBuffer,0,inputBuffer.Length);
cs.FlushFinalBlock();
}
outputBuffer=ms.ToArray();
}
返回输出缓冲区;
}
受保护的静态字节[]解密(字符串输入)
{
对称算法;
字节[]inputBuffer、inputVectorBuffer、outputBuffer;
如果(输入==null)
{
抛出新的ArgumentNullException(“输入”);
}
算法=GetCryptAlgorithm();
outputBuffer=null;
尝试
{
inputBuffer=Convert.FromBase64String(输入);
inputVectorBuffer=新字节[算法IV.Length];
数组。复制(
输入缓冲区,
输入向量缓冲区,
inputVectorBuffer.Length);
算法IV=inputVectorBuffer;
使用(var ms=new MemoryStream())
{
使用(var cs=newcryptostream)(
太太
算法。CreateDecryptor(),
CryptoStreamMode.Write)
{
写(
输入缓冲区,
inputVectorBuffer.Length,
inputBuffer.Length-inputVectorBuffer.Length);
cs.FlushFinalBlock();
}
outputBuffer=ms.ToArray();
}
}
捕获(格式化异常)
{
抛出新的加密异常(
“该字符串无法解码。”,e);
}
返回输出缓冲区;
}
//…剪断。。。
私有静态对称算法GetCryptAlgorithm()
{
对称算法;
字符串算法名;
algorithmName=machineKeyConfig.Decryption;
如果(algorithmName==“自动”)
{
抛出新的ConfigurationErrorsException(
资源。MyAwesomeClass(需要明确的算法);
}
开关(算法名称)
{
“AES”案:
算法=新的RijndaelManaged();
打破
案例“3DES”:
算法=新的TripleDESCryptoServiceProvider();
打破
“DES”案:
算法=新的DESCryptoServiceProvider();
打破
违约:
抛出新的ConfigurationErrorsException(
字符串格式(
CultureInfo.InvariantCulture,
Resources.MyAwesomeClass_无法识别的DalGorithmName,
算法名);
}
算法密钥=加密密钥;
返回算法;
}
私有静态字节[]HexStringToByteArray(字符串str)
{
字节[]缓冲区;
如果(str==null)
{
抛出新的ArgumentNullException(“str”);
}
如果(str.Length%2==1)
{
str='0'+str;
}
缓冲区=新字节[str.Length/2];
for(int i=0;i

警告买主

您可能能够重用该方法,而该方法反过来使用该类的一些(不幸的是内部)加密方法。

ASP.NET 4.0中的新类正是您想要的

例如:

public static class StringEncryptor {
    public static string Encrypt(string plaintextValue) {
        var plaintextBytes = Encoding.UTF8.GetBytes(plaintextValue);
        return MachineKey.Encode(plaintextBytes, MachineKeyProtection.All);
    }

    public static string Decrypt(string encryptedValue) {
        try {
            var decryptedBytes = MachineKey.Decode(encryptedValue, MachineKeyProtection.All);
            return Encoding.UTF8.GetString(decryptedBytes);
        }
        catch {
            return null;
        }
    }
}

更新:如前所述,请小心使用,否则可能会允许他人伪造表单身份验证令牌。

如果使用3.5或更早版本,则可以避免大量代码,只需执行以下操作:

public static string Encrypt(string cookieValue)
{
    return FormsAuthentication.Encrypt(new FormsAuthenticationTicket(1,
                                                                     string.Empty,
                                                                     DateTime.Now,
                                                                     DateTime.Now.AddMinutes(20160),
                                                                     true,
                                                                     cookieValue));
}

public static string Decrypt(string encryptedTicket)
{
    return FormsAuthentication.Decrypt(encryptedTicket).UserData;
}

我的一位同事说服了我,我认为,如果不是为了一般的加密需要,那么为定制cookie这样做是相当合理的。

对于.NET Framwork 4.5,您应该使用新的API:
public class StringProtector
{

    private const string Purpose = "Authentication Token";

    public string Protect(string unprotectedText)
    {
        var unprotectedBytes = Encoding.UTF8.GetBytes(unprotectedText);
        var protectedBytes = MachineKey.Protect(unprotectedBytes, Purpose);
        var protectedText = Convert.ToBase64String(protectedBytes);
        return protectedText;
    }

    public string Unprotect(string protectedText)
    {
        var protectedBytes = Convert.FromBase64String(protectedText);
        var unprotectedBytes = MachineKey.Unprotect(protectedBytes, Purpose);
        var unprotectedText = Encoding.UTF8.GetString(unprotectedBytes);
        return unprotectedText;
    }

}