문제

일부 데이터에 대해 매우 간단한 난독 화 (암호화 및 암호 해독이지만 반드시 안전 할 필요는없는) 기능을 찾고 있습니다. 그것은 미션 비판적이 아닙니다. 정직한 사람들을 정직하게 유지하기 위해 무언가가 필요하지만 rot13 또는 베이스 64.

나는 이미 포함 된 것을 선호합니다 .그물 프레임 워크 2.0이므로 외부 종속성에 대해 걱정할 필요가 없습니다.

나는 정말로 공개/개인 키 등을 엉망으로 만들고 싶지 않습니다. 나는 암호화에 대해 많이 알지 못하지만, 내가 쓴 것이 쓸모없는 것보다 적다는 것을 충분히 알고 있습니다. 나는 아마 수학을 망쳐 놓고 갈라지기가 사소하게 만들었습니다.

도움이 되었습니까?

해결책

여기서 다른 답변은 잘 작동하지만 AES는보다 안전하고 최신 암호화 알고리즘입니다. 이것은 몇 년 전에 시간이 지남에 따라 웹 애플리케이션에 더 친숙하기 위해 수정 한 AES 암호화를 수행하기 위해 얻은 클래스입니다 (E, G. URL 친화적 인 문자열과 함께 작동하는 암호화/해독 방법을 구축했습니다). 또한 바이트 어레이와 함께 작동하는 메소드도 있습니다.

참고 : 키 (32 바이트) 및 벡터 (16 바이트) 배열에서 다른 값을 사용해야합니다! 이 코드를 사용했다고 가정하여 누군가가 키를 알아내는 것을 원하지 않을 것입니다! 키와 벡터 배열에서 숫자 중 일부 (<= 255 여야 함)를 변경하면 벡터 배열에 하나의 유효하지 않은 값을 남겼습니다. 당신이 사용할 수있는 https://www.random.org/bytes/ 새 세트를 쉽게 생성하려면 :

사용하기 쉬운 경우 : 클래스를 인스턴스화 한 다음 (일반적으로) 암호화 (String StringToenCrypt) 및 decryptString (StringTodeCrypt)을 메소드로 호출하십시오. 이 수업을 마련하면 더 쉽지 않을 수 있습니다 (또는 더 안전한).


using System;
using System.Data;
using System.Security.Cryptography;
using System.IO;


public class SimpleAES
{
    // Change these keys
    private byte[] Key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 });

    // a hardcoded IV should not be used for production AES-CBC code
    // IVs should be unpredictable per ciphertext
    private byte[] Vector = __Replace_Me__({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 });


    private ICryptoTransform EncryptorTransform, DecryptorTransform;
    private System.Text.UTF8Encoding UTFEncoder;

    public SimpleAES()
    {
        //This is our encryption method
        RijndaelManaged rm = new RijndaelManaged();

        //Create an encryptor and a decryptor using our encryption method, key, and vector.
        EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);
        DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);

        //Used to translate bytes to text and vice versa
        UTFEncoder = new System.Text.UTF8Encoding();
    }

    /// -------------- Two Utility Methods (not used but may be useful) -----------
    /// Generates an encryption key.
    static public byte[] GenerateEncryptionKey()
    {
        //Generate a Key.
        RijndaelManaged rm = new RijndaelManaged();
        rm.GenerateKey();
        return rm.Key;
    }

    /// Generates a unique encryption vector
    static public byte[] GenerateEncryptionVector()
    {
        //Generate a Vector
        RijndaelManaged rm = new RijndaelManaged();
        rm.GenerateIV();
        return rm.IV;
    }


    /// ----------- The commonly used methods ------------------------------    
    /// Encrypt some text and return a string suitable for passing in a URL.
    public string EncryptToString(string TextValue)
    {
        return ByteArrToString(Encrypt(TextValue));
    }

    /// Encrypt some text and return an encrypted byte array.
    public byte[] Encrypt(string TextValue)
    {
        //Translates our text value into a byte array.
        Byte[] bytes = UTFEncoder.GetBytes(TextValue);

        //Used to stream the data in and out of the CryptoStream.
        MemoryStream memoryStream = new MemoryStream();

        /*
         * We will have to write the unencrypted bytes to the stream,
         * then read the encrypted result back from the stream.
         */
        #region Write the decrypted value to the encryption stream
        CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        #endregion

        #region Read encrypted value back out of the stream
        memoryStream.Position = 0;
        byte[] encrypted = new byte[memoryStream.Length];
        memoryStream.Read(encrypted, 0, encrypted.Length);
        #endregion

        //Clean up.
        cs.Close();
        memoryStream.Close();

        return encrypted;
    }

    /// The other side: Decryption methods
    public string DecryptString(string EncryptedString)
    {
        return Decrypt(StrToByteArray(EncryptedString));
    }

    /// Decryption when working with byte arrays.    
    public string Decrypt(byte[] EncryptedValue)
    {
        #region Write the encrypted value to the decryption stream
        MemoryStream encryptedStream = new MemoryStream();
        CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);
        decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
        decryptStream.FlushFinalBlock();
        #endregion

        #region Read the decrypted value from the stream.
        encryptedStream.Position = 0;
        Byte[] decryptedBytes = new Byte[encryptedStream.Length];
        encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);
        encryptedStream.Close();
        #endregion
        return UTFEncoder.GetString(decryptedBytes);
    }

    /// Convert a string to a byte array.  NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).
    //      System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    //      return encoding.GetBytes(str);
    // However, this results in character values that cannot be passed in a URL.  So, instead, I just
    // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).
    public byte[] StrToByteArray(string str)
    {
        if (str.Length == 0)
            throw new Exception("Invalid string value in StrToByteArray");

        byte val;
        byte[] byteArr = new byte[str.Length / 3];
        int i = 0;
        int j = 0;
        do
        {
            val = byte.Parse(str.Substring(i, 3));
            byteArr[j++] = val;
            i += 3;
        }
        while (i < str.Length);
        return byteArr;
    }

    // Same comment as above.  Normally the conversion would use an ASCII encoding in the other direction:
    //      System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    //      return enc.GetString(byteArr);    
    public string ByteArrToString(byte[] byteArr)
    {
        byte val;
        string tempStr = "";
        for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
        {
            val = byteArr[i];
            if (val < (byte)10)
                tempStr += "00" + val.ToString();
            else if (val < (byte)100)
                tempStr += "0" + val.ToString();
            else
                tempStr += val.ToString();
        }
        return tempStr;
    }
}

다른 팁

나는 내가 사용하기 위해 Simpleaes (위)를 정리했습니다. 수정 된 복잡한 암호화/해독 방법; 바이트 버퍼, 문자열 및 URL 친화적 인 문자열을 인코딩하는 분리 된 방법; URL 인코딩에 기존 라이브러리를 사용했습니다.

코드는 작고 단순하며 빠르며 출력이 더 간결합니다. 예를 들어, johnsmith@gmail.com 생산 :

SimpleAES: "096114178117140150104121138042115022037019164188092040214235183167012211175176167001017163166152"
SimplerAES: "YHKydYyWaHmKKnMWJROkvFwo1uu3pwzTr7CnARGjppg%3d"

암호:

public class SimplerAES
{
    private static byte[] key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 });

    // a hardcoded IV should not be used for production AES-CBC code
    // IVs should be unpredictable per ciphertext
    private static byte[] vector = __Replace_Me_({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 221, 112, 79, 32, 114, 156 });

    private ICryptoTransform encryptor, decryptor;
    private UTF8Encoding encoder;

    public SimplerAES()
    {
        RijndaelManaged rm = new RijndaelManaged();
        encryptor = rm.CreateEncryptor(key, vector);
        decryptor = rm.CreateDecryptor(key, vector);
        encoder = new UTF8Encoding();
    }

    public string Encrypt(string unencrypted)
    {
        return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted)));
    }

    public string Decrypt(string encrypted)
    {
        return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
    }

    public byte[] Encrypt(byte[] buffer)
    {
        return Transform(buffer, encryptor);
    }

    public byte[] Decrypt(byte[] buffer)
    {
        return Transform(buffer, decryptor);
    }

    protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
    {
        MemoryStream stream = new MemoryStream();
        using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
        {
            cs.Write(buffer, 0, buffer.Length);
        }
        return stream.ToArray();
    }
}

예, 추가하십시오 System.Security 어셈블리, 가져 오기 System.Security.Cryptography 네임 스페이스. 다음은 대칭 (DES) 알고리즘 암호화의 간단한 예입니다.

DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.GenerateKey();
byte[] key = des.Key; // save this!

ICryptoTransform encryptor = des.CreateEncryptor();
// encrypt
byte[] enc = encryptor.TransformFinalBlock(new byte[] { 1, 2, 3, 4 }, 0, 4);

ICryptoTransform decryptor = des.CreateDecryptor();

// decrypt
byte[] originalAgain = decryptor.TransformFinalBlock(enc, 0, enc.Length);
Debug.Assert(originalAgain[0] == 1);

암호화 된 문자열 안에 다시 전달되는 임의의 IV를 추가하여 Mud의 단순함을 개선했다고 덧붙였다. 이렇게하면 동일한 문자열을 암호화하면 매번 다른 출력이 발생하므로 암호화가 향상됩니다.

public class StringEncryption
{
    private readonly Random random;
    private readonly byte[] key;
    private readonly RijndaelManaged rm;
    private readonly UTF8Encoding encoder;

    public StringEncryption()
    {
        this.random = new Random();
        this.rm = new RijndaelManaged();
        this.encoder = new UTF8Encoding();
        this.key = Convert.FromBase64String("Your+Secret+Static+Encryption+Key+Goes+Here=");
    }

    public string Encrypt(string unencrypted)
    {
        var vector = new byte[16];
        this.random.NextBytes(vector);
        var cryptogram = vector.Concat(this.Encrypt(this.encoder.GetBytes(unencrypted), vector));
        return Convert.ToBase64String(cryptogram.ToArray());
    }

    public string Decrypt(string encrypted)
    {
        var cryptogram = Convert.FromBase64String(encrypted);
        if (cryptogram.Length < 17)
        {
            throw new ArgumentException("Not a valid encrypted string", "encrypted");
        }

        var vector = cryptogram.Take(16).ToArray();
        var buffer = cryptogram.Skip(16).ToArray();
        return this.encoder.GetString(this.Decrypt(buffer, vector));
    }

    private byte[] Encrypt(byte[] buffer, byte[] vector)
    {
        var encryptor = this.rm.CreateEncryptor(this.key, vector);
        return this.Transform(buffer, encryptor);
    }

    private byte[] Decrypt(byte[] buffer, byte[] vector)
    {
        var decryptor = this.rm.CreateDecryptor(this.key, vector);
        return this.Transform(buffer, decryptor);
    }

    private byte[] Transform(byte[] buffer, ICryptoTransform transform)
    {
        var stream = new MemoryStream();
        using (var cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
        {
            cs.Write(buffer, 0, buffer.Length);
        }

        return stream.ToArray();
    }
}

및 보너스 단위 테스트

[Test]
public void EncryptDecrypt()
{
    // Arrange
    var subject = new StringEncryption();
    var originalString = "Testing123!£$";

    // Act
    var encryptedString1 = subject.Encrypt(originalString);
    var encryptedString2 = subject.Encrypt(originalString);
    var decryptedString1 = subject.Decrypt(encryptedString1);
    var decryptedString2 = subject.Decrypt(encryptedString2);

    // Assert
    Assert.AreEqual(originalString, decryptedString1, "Decrypted string should match original string");
    Assert.AreEqual(originalString, decryptedString2, "Decrypted string should match original string");
    Assert.AreNotEqual(originalString, encryptedString1, "Encrypted string should not match original string");
    Assert.AreNotEqual(encryptedString1, encryptedString2, "String should never be encrypted the same twice");
}

마크의 변형 (우수한) 답변

  • "사용"을 추가하십시오
  • 클래스를 idisposable로 만드십시오
  • URL 인코딩 코드를 제거하여 예제를 더 간단하게 만듭니다.
  • 사용법을 보여주기 위해 간단한 테스트 고정물을 추가하십시오

도움이 되었기를 바랍니다

[TestFixture]
public class RijndaelHelperTests
{
    [Test]
    public void UseCase()
    {
        //These two values should not be hard coded in your code.
        byte[] key = {251, 9, 67, 117, 237, 158, 138, 150, 255, 97, 103, 128, 183, 65, 76, 161, 7, 79, 244, 225, 146, 180, 51, 123, 118, 167, 45, 10, 184, 181, 202, 190};
        byte[] vector = {214, 11, 221, 108, 210, 71, 14, 15, 151, 57, 241, 174, 177, 142, 115, 137};

        using (var rijndaelHelper = new RijndaelHelper(key, vector))
        {
            var encrypt = rijndaelHelper.Encrypt("StringToEncrypt");
            var decrypt = rijndaelHelper.Decrypt(encrypt);
            Assert.AreEqual("StringToEncrypt", decrypt);
        }
    }
}

public class RijndaelHelper : IDisposable
{
    Rijndael rijndael;
    UTF8Encoding encoding;

    public RijndaelHelper(byte[] key, byte[] vector)
    {
        encoding = new UTF8Encoding();
        rijndael = Rijndael.Create();
        rijndael.Key = key;
        rijndael.IV = vector;
    }

    public byte[] Encrypt(string valueToEncrypt)
    {
        var bytes = encoding.GetBytes(valueToEncrypt);
        using (var encryptor = rijndael.CreateEncryptor())
        using (var stream = new MemoryStream())
        using (var crypto = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
        {
            crypto.Write(bytes, 0, bytes.Length);
            crypto.FlushFinalBlock();
            stream.Position = 0;
            var encrypted = new byte[stream.Length];
            stream.Read(encrypted, 0, encrypted.Length);
            return encrypted;
        }
    }

    public string Decrypt(byte[] encryptedValue)
    {
        using (var decryptor = rijndael.CreateDecryptor())
        using (var stream = new MemoryStream())
        using (var crypto = new CryptoStream(stream, decryptor, CryptoStreamMode.Write))
        {
            crypto.Write(encryptedValue, 0, encryptedValue.Length);
            crypto.FlushFinalBlock();
            stream.Position = 0;
            var decryptedBytes = new Byte[stream.Length];
            stream.Read(decryptedBytes, 0, decryptedBytes.Length);
            return encoding.GetString(decryptedBytes);
        }
    }

    public void Dispose()
    {
        if (rijndael != null)
        {
            rijndael.Dispose();
        }
    }
}

편집] 몇 년 후, 나는 다시 말했다. 이것을하지 마십시오! 보다 XOR 암호화에 무슨 문제가 있습니까? 자세한 내용은.

매우 간단하고 쉬운 양방향 암호화는 XOR 암호화입니다.

  1. 비밀번호를 생각해보십시오. 하자 mypass.
  2. 암호를 바이너리로 변환합니다 (ASCII에 따라). 암호는 01101101 01111001 01110000 01100001 01110011 01110011이됩니다.
  3. 인코딩하려는 메시지를 가져 오십시오. 이진으로 변환하십시오.
  4. 메시지의 길이를보십시오. 메시지 길이가 400 바이트 인 경우 암호를 반복해서 반복하여 암호를 400 바이트 문자열로 바꾸십시오. 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 0110010010011 01110011 ... (또는 또는 또는 mypassmypassmypass...)
  5. 긴 암호로 메시지를 xor.
  6. 결과를 보내십시오.
  7. 또 다른 시간에, 동일한 비밀번호로 암호화 된 메시지를 xor (mypassmypassmypass...).
  8. 당신의 메시지가 있습니다!

나는 몇 가지 답과 의견에서 내가 가장 잘 찾은 것을 결합했습니다.

  • 임의의 초기화 벡터는 암호화 텍스트 (@JBTULE)로 선정되었습니다.
  • MemoryStream (@renniepet) 대신 변형 finalBlock ()을 사용하십시오.
  • 재난을 복사하고 붙여 넣는 사람을 피하기 위해 미리 채워진 열쇠 없음
  • 적절한 처분 및 패턴 사용

암호:

/// <summary>
/// Simple encryption/decryption using a random initialization vector
/// and prepending it to the crypto text.
/// </summary>
/// <remarks>Based on multiple answers in http://stackoverflow.com/questions/165808/simple-two-way-encryption-for-c-sharp </remarks>
public class SimpleAes : IDisposable
{
    /// <summary>
    ///     Initialization vector length in bytes.
    /// </summary>
    private const int IvBytes = 16;

    /// <summary>
    ///     Must be exactly 16, 24 or 32 bytes long.
    /// </summary>
    private static readonly byte[] Key = Convert.FromBase64String("FILL ME WITH 24 (2 pad chars), 32 OR 44 (1 pad char) RANDOM CHARS"); // Base64 has a blowup of four-thirds (33%)

    private readonly UTF8Encoding _encoder;
    private readonly ICryptoTransform _encryptor;
    private readonly RijndaelManaged _rijndael;

    public SimpleAes()
    {
        _rijndael = new RijndaelManaged {Key = Key};
        _rijndael.GenerateIV();
        _encryptor = _rijndael.CreateEncryptor();
        _encoder = new UTF8Encoding();
    }

    public string Decrypt(string encrypted)
    {
        return _encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
    }

    public void Dispose()
    {
        _rijndael.Dispose();
        _encryptor.Dispose();
    }

    public string Encrypt(string unencrypted)
    {
        return Convert.ToBase64String(Encrypt(_encoder.GetBytes(unencrypted)));
    }

    private byte[] Decrypt(byte[] buffer)
    {
        // IV is prepended to cryptotext
        byte[] iv = buffer.Take(IvBytes).ToArray();
        using (ICryptoTransform decryptor = _rijndael.CreateDecryptor(_rijndael.Key, iv))
        {
            return decryptor.TransformFinalBlock(buffer, IvBytes, buffer.Length - IvBytes);
        }
    }

    private byte[] Encrypt(byte[] buffer)
    {
        // Prepend cryptotext with IV
        byte [] inputBuffer = _encryptor.TransformFinalBlock(buffer, 0, buffer.Length); 
        return _rijndael.IV.Concat(inputBuffer).ToArray();
    }
}

2015-07-18 업데이트 : @bpsilver 및 @evereq의 의견에 따라 개인 암호화 () 메소드의 실수 고정 실수. IV는 실수로 암호화되었으며 이제 Decrypt ()에서 예상대로 명확한 텍스트로 선정되었습니다.

간단한 암호화를 원한다면 (즉, 결정된 크래커가 파손될 수 있지만 대부분의 캐주얼 사용자를 잠그는 경우), 동일한 길이의 두 개의 암호를 선택하십시오.

deoxyribonucleicacid
while (x>0) { x-- };

그리고 두 가지와 함께 데이터를 xor (필요한 경우 암호를 반복하십시오).(ㅏ). 예를 들어:

1111-2222-3333-4444-5555-6666-7777
deoxyribonucleicaciddeoxyribonucle
while (x>0) { x-- };while (x>0) { 

이진을 검색하는 사람이 DNA 문자열이 핵심이라고 생각할 수도 있지만 C 코드가 이진과 함께 저장된 비 초기의 메모리가 아닌 다른 것이라고 생각하지는 않습니다.


(ㅏ) 이건 명심하십시오 매우 간단한 암호화 및 일부 정의에 따르면 암호화의 의도는 다음과 같은 암호화로 간주되지 않을 수 있습니다. 예방하다 단순히 어렵게 만드는 것이 아니라 무단 액세스. 물론, 누군가가 강관을 사용하여 키 보유자 위에 서있을 때 가장 강력한 암호화조차도 안전하지 않습니다.

첫 번째 문장에서 언급 한 바와 같이, 이것은 캐주얼 공격자가 계속 움직일 정도로 어려운 수단입니다. 그것은 집에서 도둑질을 막는 것과 비슷합니다 - 당신은 그것을 함침 할 수 없게 만들 필요가 없으며, 옆집에있는 집보다 임신하기 어려운 것만으로도 필요합니다 :-)

암호화는 쉽습니다 : 다른 사람들이 지적했듯이 System.security.Cryptography 네임 스페이스에는 모든 작업을 수행하는 클래스가 있습니다. 집에서 재배 한 솔루션보다는 사용하십시오.

그러나 암호 해독도 쉽습니다. 당신이 가진 문제는 암호화 알고리즘이 아니라 암호 해독에 사용되는 키에 대한 액세스를 보호하는 것입니다.

다음 솔루션 중 하나를 사용합니다.

  • CurrentUser 범위와 함께 ProtectedData 클래스를 사용하는 DPAPI. 키에 대해 걱정할 필요가 없으므로 쉽습니다. 동일한 사용자가 데이터를 해독 할 수 있으므로 사용자 나 기계간에 데이터를 공유하는 데 적합하지 않습니다.

  • LocalMachine 범위와 함께 ProtectedData 클래스를 사용하는 DPAPI. 예를 들어 단일 보안 서버에서 구성 데이터를 보호하는 데 좋습니다. 그러나 기계에 로그인 할 수있는 사람은 누구나 암호화 할 수 있으므로 서버가 안전하지 않으면 좋지 않습니다.

  • 모든 대칭 알고리즘. 나는 일반적으로 어떤 알고리즘이 사용되는지 신경 쓰지 않으면 정적 symmetricalgorithm.create () 메소드를 사용합니다 (실제로 기본적으로 Rijndael). 이 경우 어떻게 든 키를 보호해야합니다. 예를 들어 어떤 식 으로든 난독 화하여 코드에 숨길 수 있습니다. 그러나 코드를 디 컴파일하기에 충분히 똑똑한 사람이라면 누구나 키를 찾을 수있을 것입니다.

위의 솔루션 중 어느 것도 내 솔루션이 단순하지 않기 때문에 솔루션을 게시하고 싶었습니다. 당신이 무슨 생각을하는지 제게 알려주세요:

 // This will return an encrypted string based on the unencrypted parameter
 public static string Encrypt(this string DecryptedValue)
 {
      HttpServerUtility.UrlTokenEncode(MachineKey.Protect(Encoding.UTF8.GetBytes(DecryptedValue.Trim())));
 }

 // This will return an unencrypted string based on the parameter
 public static string Decrypt(this string EncryptedValue)
 {
      Encoding.UTF8.GetString(MachineKey.Unprotect(HttpServerUtility.UrlTokenDecode(EncryptedValue)));
 }

선택 과목

이것은 값을 암호화하는 데 사용되는 서버의 기계 키가 값을 해독하는 데 사용되는 것과 동일하다고 가정합니다. 원하는 경우 Web.config에서 정적 머신 키를 지정하여 응용 프로그램이 실행중인 위치 (예 : 개발 대 생산 서버)에 관계없이 데이터를 해독/암호화 할 수 있습니다. 당신은 할 수 있습니다 이 지침에 따라 정적 기계 키를 생성하십시오.

TripledEscryptoserviceProvider를 사용합니다 System.Security. Cryptography :

public static class CryptoHelper
{
    private const string Key = "MyHashString";
    private static TripleDESCryptoServiceProvider GetCryproProvider()
    {
        var md5 = new MD5CryptoServiceProvider();
        var key = md5.ComputeHash(Encoding.UTF8.GetBytes(Key));
        return new TripleDESCryptoServiceProvider() { Key = key, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };
    }

    public static string Encrypt(string plainString)
    {
        var data = Encoding.UTF8.GetBytes(plainString);
        var tripleDes = GetCryproProvider();
        var transform = tripleDes.CreateEncryptor();
        var resultsByteArray = transform.TransformFinalBlock(data, 0, data.Length);
        return Convert.ToBase64String(resultsByteArray);
    }

    public static string Decrypt(string encryptedString)
    {
        var data = Convert.FromBase64String(encryptedString);
        var tripleDes = GetCryproProvider();
        var transform = tripleDes.CreateDecryptor();
        var resultsByteArray = transform.TransformFinalBlock(data, 0, data.Length);
        return Encoding.UTF8.GetString(resultsByteArray);
    }
}

네임 스페이스 System.Security.Cryptography 포함 TripleDESCryptoServiceProvider 그리고 RijndaelManaged 클래스

에 대한 참조를 추가하는 것을 잊지 마십시오 System.Security 집회.

나는 바뀌었다 이것:

public string ByteArrToString(byte[] byteArr)
{
    byte val;
    string tempStr = "";
    for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
    {
        val = byteArr[i];
        if (val < (byte)10)
            tempStr += "00" + val.ToString();
        else if (val < (byte)100)
            tempStr += "0" + val.ToString();
        else
            tempStr += val.ToString();
    }
    return tempStr;
}

이에:

    public string ByteArrToString(byte[] byteArr)
    {
        string temp = "";
        foreach (byte b in byteArr)
            temp += b.ToString().PadLeft(3, '0');
        return temp;
    }

내장 .NET 암호화 라이브러리를 사용 하여이 예제는 AES (Advanced Encryption Standard)를 사용하는 방법을 보여줍니다.

using System;
using System.IO;
using System.Security.Cryptography;

namespace Aes_Example
{
    class AesExample
    {
        public static void Main()
        {
            try
            {

                string original = "Here is some data to encrypt!";

                // Create a new instance of the Aes
                // class.  This generates a new key and initialization 
                // vector (IV).
                using (Aes myAes = Aes.Create())
                {

                    // Encrypt the string to an array of bytes.
                    byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);

                    // Decrypt the bytes to a string.
                    string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);

                    //Display the original data and the decrypted data.
                    Console.WriteLine("Original:   {0}", original);
                    Console.WriteLine("Round Trip: {0}", roundtrip);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
            }
        }
        static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key,byte[] IV)
        {
            // Check arguments.
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");
            byte[] encrypted;
            // Create an Aes object
            // with the specified key and IV.
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {

                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }


            // Return the encrypted bytes from the memory stream.
            return encrypted;

        }

        static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");

            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // Create an Aes object
            // with the specified key and IV.
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {

                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;

        }
    }
}

나는 당신이 그것이 얼마나 안전한 지 신경 쓰지 않는다고 말하지만, 당신이 선택했다면 데스 당신도 가져갈 수도 있습니다 AES 보다 최신 암호화 방법입니다.

나는 수락 된 답을 사용하고있다 마크 브리팅엄 그리고 그것은 저에게 많은 도움이되었습니다. 최근에 나는 암호화 된 텍스트를 다른 조직에 보내야했고 그곳에서 일부 문제가 발생했습니다. OP는 이러한 옵션이 필요하지 않지만 이것은 인기있는 질문이므로 수정을 게시하고 있습니다 (Encrypt 그리고 Decrypt 빌린 기능 여기):

  1. 모든 메시지에 대해 다른 IV- 육각을 얻기 전에 암호 바이트에 IV 바이트를 연결합니다. 물론 이것은 암호 텍스트를받는 당사자들에게 전달 해야하는 협약입니다.
  2. 두 개의 생성자 - 하나는 기본값을 허용합니다 RijndaelManaged 값 및 재산 값을 지정할 수있는 값 (암호화 및 암호 해독 당사자 간의 상호 계약에 따라)

다음은 클래스입니다 (끝의 테스트 샘플) :

/// <summary>
/// Based on https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx
/// Uses UTF8 Encoding
///  http://security.stackexchange.com/a/90850
/// </summary>
public class AnotherAES : IDisposable
{
    private RijndaelManaged rijn;

    /// <summary>
    /// Initialize algo with key, block size, key size, padding mode and cipher mode to be known.
    /// </summary>
    /// <param name="key">ASCII key to be used for encryption or decryption</param>
    /// <param name="blockSize">block size to use for AES algorithm. 128, 192 or 256 bits</param>
    /// <param name="keySize">key length to use for AES algorithm. 128, 192, or 256 bits</param>
    /// <param name="paddingMode"></param>
    /// <param name="cipherMode"></param>
    public AnotherAES(string key, int blockSize, int keySize, PaddingMode paddingMode, CipherMode cipherMode)
    {
        rijn = new RijndaelManaged();
        rijn.Key = Encoding.UTF8.GetBytes(key);
        rijn.BlockSize = blockSize;
        rijn.KeySize = keySize;
        rijn.Padding = paddingMode;
        rijn.Mode = cipherMode;
    }

    /// <summary>
    /// Initialize algo just with key
    /// Defaults for RijndaelManaged class: 
    /// Block Size: 256 bits (32 bytes)
    /// Key Size: 128 bits (16 bytes)
    /// Padding Mode: PKCS7
    /// Cipher Mode: CBC
    /// </summary>
    /// <param name="key"></param>
    public AnotherAES(string key)
    {
        rijn = new RijndaelManaged();
        byte[] keyArray = Encoding.UTF8.GetBytes(key);
        rijn.Key = keyArray;
    }

    /// <summary>
    /// Based on https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx
    /// Encrypt a string using RijndaelManaged encryptor.
    /// </summary>
    /// <param name="plainText">string to be encrypted</param>
    /// <param name="IV">initialization vector to be used by crypto algorithm</param>
    /// <returns></returns>
    public byte[] Encrypt(string plainText, byte[] IV)
    {
        if (rijn == null)
            throw new ArgumentNullException("Provider not initialized");

        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText cannot be null or empty");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("IV cannot be null or empty");
        byte[] encrypted;

        // Create a decrytor to perform the stream transform.
        using (ICryptoTransform encryptor = rijn.CreateEncryptor(rijn.Key, IV))
        {
            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        // Return the encrypted bytes from the memory stream.
        return encrypted;
    }//end EncryptStringToBytes

    /// <summary>
    /// Based on https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx
    /// </summary>
    /// <param name="cipherText">bytes to be decrypted back to plaintext</param>
    /// <param name="IV">initialization vector used to encrypt the bytes</param>
    /// <returns></returns>
    public string Decrypt(byte[] cipherText, byte[] IV)
    {
        if (rijn == null)
            throw new ArgumentNullException("Provider not initialized");

        // Check arguments.
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText cannot be null or empty");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("IV cannot be null or empty");

        // Declare the string used to hold the decrypted text.
        string plaintext = null;

        // Create a decrytor to perform the stream transform.
        using (ICryptoTransform decryptor = rijn.CreateDecryptor(rijn.Key, IV))
        {
            // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        // Read the decrypted bytes from the decrypting stream and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }

        return plaintext;
    }//end DecryptStringFromBytes

    /// <summary>
    /// Generates a unique encryption vector using RijndaelManaged.GenerateIV() method
    /// </summary>
    /// <returns></returns>
    public byte[] GenerateEncryptionVector()
    {
        if (rijn == null)
            throw new ArgumentNullException("Provider not initialized");

        //Generate a Vector
        rijn.GenerateIV();
        return rijn.IV;
    }//end GenerateEncryptionVector


    /// <summary>
    /// Based on https://stackoverflow.com/a/1344255
    /// Generate a unique string given number of bytes required.
    /// This string can be used as IV. IV byte size should be equal to cipher-block byte size. 
    /// Allows seeing IV in plaintext so it can be passed along a url or some message.
    /// </summary>
    /// <param name="numBytes"></param>
    /// <returns></returns>
    public static string GetUniqueString(int numBytes)
    {
        char[] chars = new char[62];
        chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
        byte[] data = new byte[1];
        using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider())
        {
            data = new byte[numBytes];
            crypto.GetBytes(data);
        }
        StringBuilder result = new StringBuilder(numBytes);
        foreach (byte b in data)
        {
            result.Append(chars[b % (chars.Length)]);
        }
        return result.ToString();
    }//end GetUniqueKey()

    /// <summary>
    /// Converts a string to byte array. Useful when converting back hex string which was originally formed from bytes.
    /// </summary>
    /// <param name="hex"></param>
    /// <returns></returns>
    public static byte[] StringToByteArray(String hex)
    {
        int NumberChars = hex.Length;
        byte[] bytes = new byte[NumberChars / 2];
        for (int i = 0; i < NumberChars; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        return bytes;
    }//end StringToByteArray

    /// <summary>
    /// Dispose RijndaelManaged object initialized in the constructor
    /// </summary>
    public void Dispose()
    {
        if (rijn != null)
            rijn.Dispose();
    }//end Dispose()
}//end class

그리고..

테스트 샘플은 다음과 같습니다.

class Program
{
    string key;
    static void Main(string[] args)
    {
        Program p = new Program();

        //get 16 byte key (just demo - typically you will have a predetermined key)
        p.key = AnotherAES.GetUniqueString(16);

        string plainText = "Hello World!";

        //encrypt
        string hex = p.Encrypt(plainText);

        //decrypt
        string roundTrip = p.Decrypt(hex);

        Console.WriteLine("Round Trip: {0}", roundTrip);
    }

    string Encrypt(string plainText)
    {
        Console.WriteLine("\nSending (encrypt side)...");
        Console.WriteLine("Plain Text: {0}", plainText);
        Console.WriteLine("Key: {0}", key);
        string hex = string.Empty;
        string ivString = AnotherAES.GetUniqueString(16);
        Console.WriteLine("IV: {0}", ivString);
        using (AnotherAES aes = new AnotherAES(key))
        {
            //encrypting side
            byte[] IV = Encoding.UTF8.GetBytes(ivString);

            //get encrypted bytes (IV bytes prepended to cipher bytes)
            byte[] encryptedBytes = aes.Encrypt(plainText, IV);
            byte[] encryptedBytesWithIV = IV.Concat(encryptedBytes).ToArray();

            //get hex string to send with url
            //this hex has both IV and ciphertext
            hex = BitConverter.ToString(encryptedBytesWithIV).Replace("-", "");
            Console.WriteLine("sending hex: {0}", hex);
        }

        return hex;
    }

    string Decrypt(string hex)
    {
        Console.WriteLine("\nReceiving (decrypt side)...");
        Console.WriteLine("received hex: {0}", hex);
        string roundTrip = string.Empty;
        Console.WriteLine("Key " + key);
        using (AnotherAES aes = new AnotherAES(key))
        {
            //get bytes from url
            byte[] encryptedBytesWithIV = AnotherAES.StringToByteArray(hex);

            byte[] IV = encryptedBytesWithIV.Take(16).ToArray();

            Console.WriteLine("IV: {0}", System.Text.Encoding.Default.GetString(IV));

            byte[] cipher = encryptedBytesWithIV.Skip(16).ToArray();

            roundTrip = aes.Decrypt(cipher, IV);
        }
        return roundTrip;
    }
}

enter image description here

나는 이것이 세계에서 가장 단순한 세계라고 생각합니다!

string encrypted = "Text".Aggregate("", (c, a) => c + (char) (a + 2));

테스트

 Console.WriteLine(("Hello").Aggregate("", (c, a) => c + (char) (a + 1)));
            //Output is Ifmmp
 Console.WriteLine(("Ifmmp").Aggregate("", (c, a) => c + (char)(a - 1)));
            //Output is Hello
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top