Basit güvensiz iki yönlü veri “gizleme”?


426

Bazı veriler için çok basit gizleme (şifrelemek ve şifresini çözmek ama mutlaka güvenli değil) arıyorum. Görev açısından kritik değil. Dürüst insanları dürüst tutmak için bir şeye ihtiyacım var, ama ROT13 veya Base64'ten biraz daha güçlü bir şeye ihtiyacım var .

Zaten .NET framework 2.0 dahil bir şey tercih ediyorum , bu yüzden herhangi bir dış bağımlılık hakkında endişelenmenize gerek yok.

Gerçekten genel / özel anahtarlar, vb. İle uğraşmak istemiyorum. Şifreleme hakkında fazla bir şey bilmiyorum, ama yazdığım her şeyin değersizden daha az olacağını bilmek için yeterli biliyorum ... Aslında, Muhtemelen matematiği bozup çatlamayı önemsiz hale getirirdim.


3
Merhaba Mark - sorun değil. Aslında çözümünü kullandığım ve gayet iyi çalıştığı için richdiet'in cevabını kabul etmem gerektiği için kötü hissettim. Ancak, diğer cevapları okumak için buraya gelmeye devam ettim ve seninki gerçekten daha iyi. İnsanlara, çalışırken daha iyi bir yanıt olduğunda bir şey yapmanın gerçekten harika bir yolu olmadığını söyleyen bir şey kullanmalarını söylemek için hiçbir neden yoktur.
Matt Dawdy

3
Kendinizi saatlerce kaydedin ve bayt dizilerinden bir URL dostu dizeye geri ve ileri dönüştürmek için HttpServerUtility.UrlTokenEn / Decode kullanın.
Praesagus

32
Kendi akıllı tasarımınızı döndürmeye çalışmadığınız için +1. Şifreleme hakkında çok şey bilmiyor olabilirsiniz, ancak şifreleme hakkında çok şey bilmeyen, ancak yine de kendi çözümlerini yaratabileceklerini düşündüğüm, tanıştığım çoğu geliştiriciden önce ışık yılı koyduğunu bildiğiniz gerçeği.
Dinah

6
Uyarı: Bu sorudaki cevapların çoğu yalnızca kimliği doğrulanmamış şifrelemedir. Bu, saldırganın uygulama fark etmeden verileri değiştirebileceği anlamına gelir . Aynı zamanda diğer ciddi güvenlik açıklarına da yol açar (dolgu kehaneti nedeniyle anahtarsız şifre çözme gibi). TL; DR: Bu konuda sorun yaşamıyorsanız, verilen cevaplardaki kodu kullanmayın veya ne dediğimi anlamıyorum.
usr

36
Bu soruya verilen tek bir yanıt güvenli şifrelemeyi tanımlamaz. Jbtule yanıtını Encrypt'te kullanın ve bunun yerine bir dizenin şifresini çözün .
CodesInChaos

Yanıtlar:


471

Buradaki diğer yanıtlar iyi çalışıyor, ancak AES daha güvenli ve güncel bir şifreleme algoritmasıdır. Bu, web uygulamaları için daha kolay olacak şekilde zaman içinde değiştirdiğim AES şifrelemesini gerçekleştirmek için birkaç yıl önce elde ettiğim bir sınıftır (ör. URL dostu dize ile çalışan Şifreleme / Şifre Çözme yöntemleri oluşturdum). Ayrıca bayt dizileri ile çalışan yöntemlere sahiptir.

NOT: Anahtar (32 bayt) ve Vektör (16 bayt) dizilerinde farklı değerler kullanmalısınız! Birisinin sadece bu kodu olduğu gibi kullandığınızı varsayarak anahtarlarınızı çözmesini istemezsiniz! Tek yapmanız gereken, Anahtar ve Vektör dizilerindeki bazı sayıları değiştirmek (<= 255 olmalıdır) (Bunu yaptığınızdan emin olmak için Vector dizisinde bir geçersiz değer bıraktım ...). KullanabilirsinizKolayca yeni bir set oluşturmak https://www.random.org/bytes/ adresini :

Bunu kullanmak kolaydır: sadece sınıfı başlatın ve yöntemler olarak (genellikle) EncryptToString (string StringToEncrypt) ve DecryptString (string StringToDecrypt) öğelerini çağırın. Bu sınıfı uyguladıktan sonra daha kolay (veya daha güvenli) olamazdı.


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

53
@AndyMcKenna - İkinci paragrafta Mark'ın belirttiği gibi, dizilerdeki değerleri değiştirmek için bilerek yapılmıştır.
Pauk

42
IV'ü böyle kullanmamalısınız. Belirli bir iki mesaj için, aynı Anahtar ve aynı IV ile şifrelenmemiş olmalıdırlar. IV her mesaj için rasgele olmalı, kripto akımına eklenmiş olmalı ve şifre çözmeden önce okunmalıdır. crypto.stackexchange.com/a/82/1934
jbtule

30
Her mesaj için rastgele bir IV kullanmak egzotik veya yeni değildir, sadece önemli ve algoritmanın tasarımının bir parçasıdır. Her mesaj için öngörülebilir bir IV kullanmak, sürdürülmesi gerekmeyen yaygın bir kripto hatasıdır.
jbtule

14
CBC'nin modu olarak kullanılmasının bir sonucunun, kehanet saldırılarına karşı savunmasız olmanızın muhtemel olduğunu unutmayın . Kimliği doğrulanmış şifreleme kullanın ve mümkün olduğunda şifrelemeyi kendiniz uygulamayın .
Stephen Touset

57
Güvenlik Uyarısı: Bu Kodu Kullanmayın Kabul edilen cevap olmasına rağmen, yukarıdaki yorumlarda yazarın 8 yıldır görmezden gelmeye devam ettiği ciddi güvenlik sorunları bulunmaktadır.
jbtule

176

Kullanımım için SimpleAES'i (yukarıda) temizledim. Sabit kıvrımlı şifreleme / şifre çözme yöntemleri; bayt tamponlarını, dizeleri ve URL dostu dizeleri kodlamak için ayrılmış yöntemler; URL kodlaması için mevcut kitaplıklardan yararlandı.

Kod küçük, daha basit, daha hızlı ve çıktı daha özlü. Örneğin, aşağıdakileri johnsmith@gmail.comüretir:

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

Kod:

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

2
Kod çözme sırasında, Chrome'da QueryString ile çalışması için boşluğu + ile değiştirmek zorunda kaldım: (yeni SimplerAES ()).
canlı aşk

20
Hiçbir zaman sabit bir Başlatma Vektörü kullanmayın, nedeniyle ilgili daha fazla bilgi için crypto.stackexchange.com/questions/66/… adresine bakın . Bunun yerine, her şifreleme için yeni bir IV oluşturun ve şifreli metne ekleyin, çok daha iyi ve zor değil.
Tom Heard

2
Bu çözümdeki EncryptToUrl yönteminin çıktısının (veya genel olarak UrlEncoded temel 64 dizesinin herhangi bir şekilde kullanılmasının), URL yolunun (sorgu dizesi değil) parçası olarak kullanıldığında IIS 7 altında varsayılan olarak çalışmadığını unutmayın IIS 7 güvenlik ayarı nedeniyle bir ASP.NET MVC yolu. Daha fazla bilgi için, bkz. Stackoverflow.com/a/2014121/12484
Jon Schneider

5
@TomHeard Yukarıdaki kodla bunu nasıl yapabilirim?
MKII

26
Güvenlik Uyarısı: Bu Kodu Kullanmayın @TomHeard tarafından yapılan yoruma bakın
jbtule

36

Evet, System.Securitymontajı ekleyin , System.Security.Cryptographyad alanını içe aktarın . Simetrik (DES) algoritma şifrelemesinin basit bir örneği:

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

5
Bu güzel, kompakt iki yönlü bir şifreleme. Tek uyarı, DES'in artık en gelişmiş güvenlik olarak kabul edilmemesidir. Bu başlık şimdi aşağıda tartıştığım AES algoritmasına gidiyor.
Mark Brittingham

@richdiet. Cevabınızı kabul etmediğim için üzgünüm. 37+ oy ile diğer cevap daha güncel çünkü. Hala iyi bir yanıt olduğu için cevabınız için teşekkür ederim.
Matt Dawdy

14
@MarkBrittingham: blok zincirleme fonksiyonu, başlatma vektörü ve uygun dolgu olmadan herhangi bir blok şifreleme güvensizdir. DES'i kullanmak bu şemadaki en önemli problemdir.
Hubert Kario

2
Peki anahtar nerede kullanılıyor?
Alex

22
Güvenlik Uyarısı: Bu Kodu Kullanmayın @HubertKario tarafından yapılan açıklamaya bakın
jbtule

28

Şifrelenmiş dize içine aktarılan rastgele bir IV ekleyerek Mud'un SimplerAES'ini geliştirdiğimi eklediğimi düşündüm. Bu, aynı dizeyi şifrelemek her seferinde farklı bir çıktıya neden olacağından şifrelemeyi geliştirir.

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

Ve bonus birim testi

[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");
}

11
1) System.RandomRNG olarak kullanmayın . 2) Bu, seçilen şifreli metin saldırılarına (özellikle dolgu-
oracles

21
Güvenlik Uyarısı: Bu Kodu Kullanmayın, yukarıdaki yoruma bakınız @CodesInChaos
jbtule

@jbtule lütfen komplikasyonları istemeyen herkese yanlış davranmayın ve aynı zamanda saldırı hakkında dikkatli olmayan, - Öneri vermek istiyorsanız lütfen sipariş vermeyin.
Virbhadrasinh

@Virbhadrasinh benim açımdan yanlış yönlendirici bir şey yok, aslında tam tersi. AES'yi kullanacaksanız, doğru kullanmak oldukça önemlidir, yanlış kullanmak ve önemli olduğunu söylemek önemli bir şey için kullanmıyorum, yanlış yönlendirilmiş.
jbtule

1
@Corey Bağırmıyor ve yığın taşması yanıtlarında güvenlik sorunları ile başa çıkmak için en iyi uygulamayı izlemişti. Bir bağlantı istiyorsanız, soru yorumlarında yayınlanmıştır. Ama senin için de buraya koyacağım stackoverflow.com/a/10366194/637783
jbtule

12

Bir çeşit Marks (mükemmel) cevabı

  • "Using" s ekle
  • Sınıfı kimliğini imkansız hale getirme
  • Örneği daha basit hale getirmek için URL kodlama kodunu kaldırın.
  • Kullanımı göstermek için basit bir test fikstürü ekleyin

Bu yardımcı olur umarım

[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();
        }
    }
}

İyi cevap. Dispose yönteminde bir şey IDIposable için rijndael döküm gerekir veya Dispose
John ClearZ

8
Hiçbir zaman sabit bir Başlatma Vektörü kullanmayın, nedeniyle ilgili daha fazla bilgi için crypto.stackexchange.com/questions/66/… adresine bakın. Bunun yerine, her şifreleme için yeni bir IV oluşturun ve şifreli metne ekleyin, çok daha iyi ve zor değil.
Tom Heard

5
@Chalky Şifrelemede, sizin için rastgele bir IV oluşturmak için Rijndael sınıfını kullanırsınız ( msdn.microsoft.com/en-us/library/… ), şifrelemenizi yapın ve IV özelliğini kullanarak IV'ü Rijndael örneğinden yakalayın . Daha sonra, şifresini aynı taraftan yakaladığı sürece kripto metninizin başına eklersiniz (veya ekleyebilirsiniz). Şifre çözüldükten sonra IV'ü alınan verilerden çekin (IV özelliğinin boyutu, BlockSize özelliğinin 8'e bölünmesiyle aynıdır), ardından şifresini çözmeden önce şifresini çözme örneğinize iletin.
Tom Heard

2
@Chalky IV'ün gizli olması gerekmediğini, gönderilen her mesaj için benzersiz olması gerektiğini unutmayın.
Tom Heard

20
Güvenlik Uyarısı: Bu Kodu Kullanma Yukarıdaki yukarıya bakın Yorumlar @TomHeard tarafından
jbtule

8

[EDIT] Yıllar sonra tekrar şunu söylemeye geldim: Bunu yapma! Bkz. XOR şifrelemesinde sorun nedir? detaylar için.

Çok basit, kolay iki yönlü şifreleme XOR şifrelemesidir.

  1. Bir şifre ile gel. Haydi olsun mypass.
  2. Parolayı ikili dosyaya dönüştürün (ASCII'ye göre). Parola 01101101 01111001 01110000 01100001 01110011 01110011 olur.
  3. Kodlamak istediğiniz mesajı alın. Bunu ikili dosyaya da dönüştürün.
  4. Mesajın uzunluğuna bakın. İleti uzunluğu 400 bayt ise, parolayı tekrar tekrar tekrar 400 bayt dizeye dönüştürün. 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011 ... (veyamypassmypassmypass... )
  5. İletiyi uzun parolayla XOR.
  6. Sonucu gönderin.
  7. Başka bir zaman, aynı şifreye sahip şifreli mesajı XOR (mypassmypassmypass... ).
  8. Mesajınız burada!

10
@Ryan Her durum kriptografik olarak güvenli karma veya Rijndael şifreleri gerektirmez. "Basit 2 yönlü şifreleme" aslında basit anlamına gelebilir , bu da xor hatta ROT13'ü önerir.

1
@Ryan: Statik şifreleme anahtarı, başlatma vektörü ve blok zincirleme işlevi olmayan AES, XOR şifrelemesi için sadece süslü bir isim, sadece gerçekten süslü KDF kullanıyorsunuz ...
Hubert Kario

17
Güvenlik Uyarısı: Bu Kodu Kullanmayın XOR Şifreleme, yinelenen bir anahtarla tamamen kırılmıştır.
jbtule

7

Birkaç cevap ve yorumdan en iyi bulduğumu birleştirdim.

  • Kripto metninin başına rastgele başlatma vektörü (@jbtule)
  • MemoryStream (@RenniePet) yerine TransformFinalBlock () kullanın
  • Kimsenin bir felaketi kopyalayıp yapıştırmasını önlemek için önceden doldurulmuş anahtarlar yok
  • Uygun atma ve kullanma kalıpları

Kod:

/// <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();
    }
}

Güncelleme 2015-07-18: @bpsilver ve @Evereq yorumlarıyla özel Encrypt () yönteminde hata düzeltildi. IV yanlışlıkla şifrelenmiştir, şimdi Decrypt () tarafından beklendiği gibi açık metin olarak eklenmiştir.


İnputBuffer öğesinin tamamını IV eklenmiş olarak şifrelemeniz gerekir, aksi takdirde dizgiden-şifrelemenin ilk 16 karakteri kaybolur. Kodunuz şu şekilde olmalıdır:return _encryptor.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);
bpsilver

2
Bu durumda:byte [] inputBuffer = _encryptor.TransformFinalBlock(buffer, 0, buffer.Length); return _rijndael.IV.Concat(inputBuffer).ToArray();
bpsilver

1
Mevcut uygulama ile aynı şeyi yapar, değil mi?
angularsen

1
"16, 24 VEYA 32 CHARS İLE DOLAYIN" iyi, hayır, taban 64 kod çözme işleminden önce değil . Ve bir anahtar rastgele olmalı. Gerçekten rastgele.
Maarten Bodewes

1
@Bpsilver sağ ve sağlanan kod düzeltmek olmadan çalışmaz dikkat edin: şifreleme yöntemi IV olmadan şifreli veri döndürür (ilk önce inputbuffer IV ekler, ancak sonraki şifrelemek ve onsuz veri döndürür). Bu yüzden mümkünse cevabı koduyla güncelleyin. (Not: Dizeleri değil, yalnızca byte [] parametreleri olan yöntemleri test ederim). Teşekkürler!
Evereq

6

Sadece basit şifreleme istiyorsanız (yani, belirli bir krakerin kırılması mümkündür, ancak çoğu sıradan kullanıcıyı kilitler), sadece eşit uzunlukta iki parola seçin:

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

ve verilerinizi her ikisiyle de xor (gerekirse parolaları döngüye sokmak) (a) . Örneğin:

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

İkili dosyalarınızı arayan bir kişi DNA dizesinin bir anahtar olduğunu düşünebilir, ancak C kodunun ikili kodunuzla kaydedilen başlatılmamış bellek dışında bir şey olduğunu düşünmesi olası değildir.


(a) Bunun çok basit bir şifreleme olduğunu ve bazı tanımlarla şifreleme olarak kabul edilemeyeceğini unutmayın (şifrelemenin amacı, yalnızca zorlaştırmak yerine yetkisiz erişimi önlemektir ). Tabii ki, en güçlü şifreleme bile, bir çelik boru ile anahtarlıkların üzerinde durduğunda güvensizdir.

İlk cümlede belirtildiği gibi, bu, sıradan saldırganın ilerleyeceklerini zorlaştırmanın bir yoludur. Evinizdeki hırsızlıkları önlemeye benzer - onu emprenye etmenize gerek yok, sadece yanındaki kapıdan daha az pregnable yapmalısınız :-)


3
İlginç fikir. Bir ikili kod kaynak "inanmak" emin değilim - ama bir parola olarak bir hata iletisi kullanmak için fikir uyarlamaya ne dersiniz?
Jon Skeet

1
Ben zaten uygulamada (hata mesajı ya da öylesine) var bazı cleartext dize md5 karma kullanmayı tercih.
Treb

2
Neden eşit uzunlukta olmaları gerekiyor? Farklı uzunluklarda olmaları aslında daha iyi görünüyor. Bu şekilde, etkili XOR işleneninizin uzunluğu, sadece length1 (= length2) yerine LCM'dir (uzunluk1, uzunluk2). Uzunluklar nispeten asalsa, elbette uzunluk1 * uzunluk2 olur.
Fantius

15
Güvenlik Uyarısı: Bu Kodu Kullanmayın Yinelenen anahtar XOR, şifrelenen verilerin genel bilgisiyle kolayca kırılabilir.
jbtule

3
@jbtule, soruyu okursanız, daha güvenli şifrelemenin hiçbir şekilde gerekli olmadığını fark edersiniz. Özellikle 'basit şifreleme', 'kritik görev değil' ve sadece 'dürüst insanları dürüst tutma' referansı. Ayrıca, kararlı saldırganları kilitlemeyeceğini açıkça belirten ilk paragrafımı da okumalısınız.
paxdiablo

5

Şifreleme kolaydır: diğerlerinin de belirttiği gibi, System.Security.Cryptography ad alanında tüm işleri sizin için yapan sınıflar vardır. Bunları evde yetiştirilen herhangi bir çözüm yerine kullanın.

Ancak şifre çözme de kolaydır. Sahip olduğunuz sorun şifreleme algoritması değil, şifre çözme için kullanılan anahtara erişimi korumak.

Aşağıdaki çözümlerden birini kullanırdım:

  • CurrentUser kapsamıyla ProtectedData sınıfını kullanan DPAPI. Bir anahtar için endişelenmenize gerek olmadığından bu kolaydır. Verilerin şifresi sadece aynı kullanıcı tarafından çözülebilir, bu nedenle kullanıcılar veya makineler arasında veri paylaşımı için uygun değildir.

  • LocalMachine kapsamına sahip ProtectedData sınıfını kullanan DPAPI. Tek bir güvenli sunucuda yapılandırma verilerini korumak için iyi. Ancak makinede oturum açabilen herkes şifreleyebilir, bu nedenle sunucu güvenli olmadığı sürece iyi olmaz.

  • Herhangi bir simetrik algoritma. Hangi algoritmanın kullanıldığını umursamadığımda genellikle statik SymmetricAlgorithm.Create () yöntemini kullanıyorum (aslında varsayılan olarak Rijndael). Bu durumda anahtarınızı bir şekilde korumanız gerekir. Örneğin, bir şekilde gizleyebilir ve kodunuzda gizleyebilirsiniz. Ancak, kodunuzu koda çevirecek kadar akıllı olan herkesin anahtarı bulabileceğini unutmayın.


5

Yukarıdaki çözümlerin hiçbiri benim kadar basit olmadığından çözümümü göndermek istedim. Ne düşündüğü söyle:

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

İsteğe bağlı

Bu, değeri şifrelemek için kullanılan sunucunun MachineKey değerinin şifresini çözmek için kullanılan sunucuyla aynı olduğunu varsayar. İstenirse, Web.config dosyasında statik bir MachineKey belirtebilirsiniz, böylece uygulamanız nerede çalıştığından bağımsız olarak verilerin şifresini çözebilir / şifreleyebilir (örn. Geliştirme ve üretim sunucusu). Sen olabilir bu talimatları uygulayarak statik makine anahtarı oluşturmak .


Bu yaklaşımın yalnızca ASP.NET uygulaması için kullanılabileceğini unutmayın.
Feru

2

Ad alanı ve öğelerini System.Security.Cryptographyiçerir.TripleDESCryptoServiceProviderRijndaelManaged sınıflarını

Derlemeye başvuru eklemeyi unutmayın System.Security.


8
Düşündüğümden değil, ama oy kullanırken bir sorunun yaşı neden önemlidir?
user247702

2

System.Security.Cryptography'de TripleDESCryptoServiceProvider Kullanımı :

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

1

Değiştim bu :

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

buna:

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

1

Yerleşik .Net Şifreleme kitaplığını kullanan bu örnek, Gelişmiş Şifreleme Standardının (AES) nasıl kullanılacağını gösterir.

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;

        }
    }
}

0

Ben size ne kadar güvenli umurumda değil dedi biliyorum ama seçtiyseniz DES siz de alabilir AES daha yukarı güncel şifreleme metodudur.


0

Mark Brittingham'ın kabul ettiği cevabı kullanıyorum ve bana çok yardımcı oldu. Son zamanlarda farklı bir kuruluşa şifreli metin göndermek zorunda kaldım ve işte bu noktada bazı sorunlar ortaya çıktı. OP bu seçenekleri gerektirmez, ancak bu popüler bir soru olduğu için modifikasyonumu gönderiyorum ( Encryptve buradanDecrypt ödünç alınan işlevler ):

  1. Her mesaj için farklı IV - Heks'i elde etmeden önce IV baytlarını şifre baytlarına birleştirir. Elbette bu, şifre metnini alan taraflara iletilmesi gereken bir sözleşmedir.
  2. İki yapıcıya izin verir - biri varsayılan RijndaelManageddeğerler için, diğeri özellik değerlerinin belirtilebildiği (şifreleme ve şifre çözme tarafları arasındaki karşılıklı anlaşmaya dayanarak)

İşte sınıf (sonunda test örneği):

/// <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

ve..

İşte test örneği:

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

resim açıklamasını buraya girin


-2

Bence bu dünyanın en basit olanı!

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

Ölçek

 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

ROT ... 1? Gerçekten mi? OP bile o şeyin bir örnek olarak rot13 seslendi vermedi yapmak istiyorum.
user812786
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.