programing

ASP 활용.자체 데이터 암호화를 위한 NET machineKey

batch 2023. 8. 9. 20:35
반응형

ASP 활용.자체 데이터 암호화를 위한 NET machineKey

ASP에 암호화할 데이터가 있습니다.사용자의 조작을 방지하기 위한 NET MVC 응용 프로그램입니다.암호화 클래스를 사용하여 실제 암호화/암호 해독을 수행할 수 있습니다. 문제가 없습니다.주요 문제는 암호화 키를 저장할 위치를 파악하고 변경 사항을 관리하는 것입니다.

ASP 이후.NET은 이미 다양한 것(ViewData 암호화 등)을 위한 machineKey를 유지하고 있는데, ASP가 있는지 궁금합니다.machineKey를 사용하여 내 데이터를 암호화/암호 해독할 수 있는 NET 기능?이렇게 하면 키 관리 시스템을 직접 설계할 필요가 없습니다.

.NET Framework 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;
    }

}

이상적으로 "목적"은 단조를 방지하기 위해 알려진 한 번의 유효한 값이어야 합니다.

ASP의 새 MachineKey 클래스입니다.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;
        }
    }
}

업데이트: 여기서 언급한 것처럼, 이것을 사용하는 방법에 주의하십시오. 그렇지 않으면 다른 사람이 양식 인증 토큰을 위조하도록 허용할 수 있습니다.

직접적인 건 아닌 것 같아요.제가 이걸 어디서 구했는지 기억이 안 나요. 아마도 리플렉터와 몇몇 블로그를 합친 것 같아요.

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;
    }
}

조심해요!

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;
}

제 동료 중 한 명이 저를 설득하여 일반적인 암호화 요구 사항이 아니라면 사용자 지정 쿠키에 대해 이 작업을 수행하는 것이 상당히 합리적이라고 생각합니다.

구성원 자격 공급자를 다시 사용할 수 있습니다.EncryptPassword 메서드는 MachineKeySection 클래스의 일부(불행히도 내부) 암호화 메서드를 사용합니다.

언급URL : https://stackoverflow.com/questions/3681493/leveraging-asp-net-machinekey-for-encrypting-my-own-data

반응형