我正在为某些数据寻找非常简单的混淆(如加密和解密但不一定是安全的)功能。 这不是关键任务。 我需要一些东西来保持诚实的人诚实,但比ROT13或Base64强一点。

我更喜欢已经包含在.NET framework 2.0中的东西,所以我不必担心任何外部依赖。

我真的不想乱用公钥/私钥等等。我对加密知之甚少,但我知道我写的任何内容都不会毫无价值......事实上,我可能搞砸了数学并且让它变得微不足道。


#1楼

命名空间System.Security.Cryptography包含TripleDESCryptoServiceProviderRijndaelManaged

不要忘记添加对System.Security程序集的引用。


#2楼

是的,添加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);

#3楼

如果你只是想要简单的加密(即,确定的破解者可能会破坏,但锁定大多数临时用户),只需选择两个相等长度的密码,例如:

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

和xor你的数据(必要时循环密码) (a) 。 例如:

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

搜索你的二进制文件的人可能会认为DNA字符串是一个关键字,但他们不太可能认为C代码不是用二进制文件保存的未初始化内存。


(a)请记住,这是非常简单的加密,并且根据某些定义,可能根本不被视为加密(因为加密的目的是防止未经授权的访问而不仅仅是使其更加困难)。 当然,当有人用钢管架住钥匙扣时,即使最强的加密也是不安全的。

如第一句中所述,这是一种让偶然攻击者难以继续前进的手段。 它类似于防止你家的盗窃 - 你不需要让它变得坚不可摧,你只需要让它比隔壁的房子更难以预防:-)


#4楼

我知道你说你不关心它的安全性,但是如果你选择DES,你可能会选择AES,这是更新的加密方法。


#5楼

加密很容易:正如其他人所指出的那样,System.Security.Cryptography命名空间中有一些类可以为您完成所有工作。 使用它们而不是任何本土解决方案。

但解密也很容易。 您遇到的问题不是加密算法,而是保护对用于解密的密钥的访问。

我会使用以下解决方案之一:

  • 使用带有CurrentUser范围的ProtectedData类的DPAPI。 这很简单,因为您不必担心密钥。 数据只能由同一用户解密,因此无法在用户或计算机之间共享数据。

  • 使用带有LocalMachine范围的ProtectedData类的DPAPI。 适用于保护单个安全服务器上的配置数据。 但是任何可以登录机器的人都可以加密它,所以除非服务器是安全的,否则没有好处。

  • 任何对称算法。 如果我不关心使用什么算法(实际上它默认是Rijndael),我通常使用静态SymmetricAlgorithm.Create()方法。 在这种情况下,您需要以某种方式保护您的密钥。 例如,您可以以某种方式对其进行模糊处理并将其隐藏在代码中。 但请注意,任何聪明到足以反编译代码的人都可能找到密钥。


#6楼

这里的其他答案工作正常,但AES是一种更安全和最新的加密算法。 这是我几年前用来执行AES加密的类,我已经修改了一段时间以便对Web应用程序更友好(例如,我已经构建了使用URL友好字符串的加密/解密方法)。 它还具有与字节数组一起使用的方法。

注意:您应该在Key(32字节)和Vector(16字节)数组中使用不同的值! 您不希望有人通过假设您按原样使用此代码来弄清楚您的密钥! 您所要做的就是更改Key和Vector数组中的一些数字(必须<= 255)(我在Vector数组中保留了一个无效值以确保您执行此操作...)。 您可以使用https://www.random.org/bytes/轻松生成新集:

  • 生成Key
  • 生成Vector

使用它很简单:只需实例化类,然后调用(通常)EncryptToString(string StringToEncrypt)和DecryptString(string StringToDecrypt)作为方法。 一旦你有这个课程,它就不会更容易(或更安全)。


using System;
using System.Data;
using System.Security.Cryptography;
using System.IO;public class SimpleAES
{// Change these keysprivate 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 ciphertextprivate 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 methodRijndaelManaged 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 versaUTFEncoder = 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 vectorstatic public byte[] GenerateEncryptionVector(){//Generate a VectorRijndaelManaged 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 streamCryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);cs.Write(bytes, 0, bytes.Length);cs.FlushFinalBlock();#endregion#region Read encrypted value back out of the streammemoryStream.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 methodspublic 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 streamMemoryStream 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();#endregionreturn 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();elsetempStr += val.ToString();}return tempStr;}
}

#7楼

[编辑]多年以后,我回来说: 不要这样做! 看看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 01100001 01110011 01110011 ...(或mypassmypassmypass...
  5. 使用长密码对消息进行异或。
  6. 发送结果。
  7. 另一次,XOR加密的消息使用相同的密码( mypassmypassmypass... )。
  8. 有你的消息!

#8楼

只是想我会补充一点,我通过添加一个随机的IV来改进Mud的SimplerAES,这个随机的IV被传回加密的字符串。 这改进了加密,因为加密相同的字符串每次都会导致不同的输出。

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()
{// Arrangevar subject = new StringEncryption();var originalString = "Testing123!£$";// Actvar encryptedString1 = subject.Encrypt(originalString);var encryptedString2 = subject.Encrypt(originalString);var decryptedString1 = subject.Decrypt(encryptedString1);var decryptedString2 = subject.Decrypt(encryptedString2);// AssertAssert.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");
}

#9楼

我从几个答案和评论中结合了我发现的最好的东西。

  • 随机初始化向量前置加密文本(@jbtule)
  • 使用TransformFinalBlock()而不是MemoryStream(@RenniePet)
  • 没有预先填写的密钥,以避免任何人复制和粘贴灾难
  • 正确处置和使用模式

码:

/// <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 cryptotextbyte[] 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 IVbyte [] inputBuffer = _encryptor.TransformFinalBlock(buffer, 0, buffer.Length); return _rijndael.IV.Concat(inputBuffer).ToArray();}
}

更新2015-07-18:通过@bpsilver和@Evereq的注释修复了私有Encrypt()方法中的错误。 IV被意外加密,现在以Decrypt()预期的明文前缀。


#10楼

我认为这是世界上最简单的一个!

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

测试

 Console.WriteLine(("Hello").Aggregate("", (c, a) => c + (char) (a + 1)));//Output is IfmmpConsole.WriteLine(("Ifmmp").Aggregate("", (c, a) => c + (char)(a - 1)));//Output is Hello

#11楼

我想发布我的解决方案,因为上述解决方案都不像我的那么简单。 让我知道你的想法:

 // This will return an encrypted string based on the unencrypted parameterpublic static string Encrypt(this string DecryptedValue){HttpServerUtility.UrlTokenEncode(MachineKey.Protect(Encoding.UTF8.GetBytes(DecryptedValue.Trim())));}// This will return an unencrypted string based on the parameterpublic static string Decrypt(this string EncryptedValue){Encoding.UTF8.GetString(MachineKey.Unprotect(HttpServerUtility.UrlTokenDecode(EncryptedValue)));}

可选的

这假定用于加密该值的服务器的MachineKey与用于解密该值的服务器的MachineKey相同。 如果需要,您可以在Web.config中指定静态MachineKey,以便您的应用程序可以解密/加密数据,无论数据在何处运行(例如开发与生产服务器)。 您可以按照这些说明生成静态机器密钥 。


#12楼

使用内置的.Net Cryptography库,此示例显示了如何使用高级加密标准(AES)。

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

#13楼

我一直在使用Mark Brittingham接受的答案,它给了我很多帮助。 最近我不得不将加密文本发送到另一个组织,这就是出现问题的地方。 OP不需要这些选项,但由于这是一个流行的问题,我发布了我的修改(从这里借来的EncryptDecrypt函数):

  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 Vectorrijn.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!";//encryptstring hex = p.Encrypt(plainText);//decryptstring 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 sidebyte[] 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 ciphertexthex = 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 urlbyte[] 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;}
}


#14楼

System.Security.Cryptography中使用TripleDESCryptoServiceProvider:

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

#15楼

我改变了这个 :

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();elsetempStr += val.ToString();}return tempStr;
}

对此:

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

#16楼

我清理了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 ciphertextprivate 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();}
}

#17楼

Marks(优秀)答案的变体

  • 添加“使用”s
  • 使类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();}}
}

C#的简单不安全双向“混淆”相关推荐

  1. SurfaceView简单理解,Android混淆,Android openGl开发详解简单图形的绘制,

    SurfaceView允许你在非ui线程中去绘制. SurfaceView的帧率可以操作60FPS 在要求实时性比较高的游戏开发中,显然,view的ondraw是满足不了你的,这时候只能是用Surfa ...

  2. 实现简单的带头双向循环链表

    双向链表 1. 带头双向循环链表的定义 2. 带头双向循环链表的创建 3. 带头双向循环链表的增删改查 (1)头插头删 (2)尾插尾删 (3)pos位置的前插与删除 4.插入与删除改良 1. 带头双向 ...

  3. 用JS简单实现Vue的双向绑定

    Vue实现数据双向绑定原理: 采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者, ...

  4. 混淆工具Dotfuscator基本使用

    Dotfuscator是dnet程序混淆工具:混淆,就是搞乱代码,代码功能完全不变:这样反汇编以后难以阅读:以保护自己的知识产权: 此工具是微软提供的:可以从VS安装:也可以单独下安装包: 安装完: ...

  5. ASP.NET Core 3.0 gRPC 双向流

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 认证授权 一.前言 在前一文 < 二. 什么 ...

  6. “约见”面试官系列之常见面试题第九篇vue实现双向绑定原理(建议收藏)

    目录 1.原理 2.实现 在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫m ...

  7. Android代码混淆方法,Android 代码混淆零基础入门

    内容提要 本篇文章主要有三个部分,让读者读完后能自己写规则混淆项目 对Android代码怎么开启混淆做一个简单的介绍. 对混淆规则做一个简单介绍: 在混淆过后Crash日志反推代码工具retrace. ...

  8. c语言一次绑定多个控件,一入前端深似海,从此红尘是路人系列第九弹之如何实现一个双向数据绑定...

    前言 简单介绍一下双向数据绑定实现的是一个什么样的东西.首先有两个东西,他们分别是: V-视图层 M-数据层 1.视图层传向数据层:V发生改变,M也发生改变 2.数据层传向视图层:M发生改变,V也发生 ...

  9. *oulapp的双向证书破解

    *oulapp的双向证书破解 今天简单说一下双向证书的破解,顺便说一个比较好用的工具,案例: c291bA== 破解双向证书: 之前见过单向证书校验,比如企查查.饿了么等,这个最简单的方法就是使用Ju ...

最新文章

  1. Ajax的进阶学习(一)
  2. oracle数据库备份方法主要有哪几种,Oracle数据库备份方法有哪三种?
  3. SuperEdge — Overview
  4. 她说要介绍10000个开源项目?来!我们一起监督!
  5. [hdu5266]区间LCA
  6. yii2 mysql like_Yii2实现跨mysql数据库关联查询排序功能
  7. 一直在构建版本_球鞋 | 一鞋两穿?AJ1十孔版本登场,拉链设计还是真香了?
  8. C++求字符串长度的两种方法
  9. Linux的奖励机制是啥意思,Linux能力(capability)机制的继承
  10. poj-3185-开关问题
  11. 【BIT2021程设】2. 解谜游戏——初见DFS
  12. ubuntu/deepin安装配置mysql
  13. 再见,百度网盘!新 60MB/s!
  14. 盘点8个高效方法提高睾酮水平
  15. win7计算机管理无用户账户,win7系统控制面板中用户账户显示空白的解决方法
  16. 服务器维护10月11魔兽,魔兽世界怀旧服10月11日免费转服第五期开启公告 免费转服详情...
  17. react native 的button点击变色以及禁用问题
  18. 刚刚,数学界“诺奖”Abel Prize迎来首位女性得主
  19. Hibernate学习(一)
  20. Java修真之练气筑基篇(持续更新)

热门文章

  1. 操作系统就是一个“死循环”?
  2. 【Android】Service几个重要的方法运行在哪个线程
  3. java同步机制:synchronized
  4. 用户月活跃度在哪里可以查_2020年12月计算机等级考试报名时间,另外11月6号可以查9月考试成绩...
  5. SwiftUI 发展现状和学习指南
  6. Foundation框架介绍
  7. vmware-tools安装说明
  8. 使用PHPStorm 配置自定义的Apache与PHP环境
  9. 20165224 陆艺杰 网络攻防 实验1
  10. 2018-2019-1 20165305 实验三 实时系统