CSharp - C# 简单的双向加密。

  显示原文与译文双语对照的内容

我正在寻找一些数据的简单加密和解密功能。 这不是任务关键。我需要一些让诚实人诚实的东西,但是有些比 ROT13 或者 Base64更强大的东西。

我更喜欢在 .NET 框架 2.0中包含的东西,所以我不需要担心任何外部依赖。

我真的不想使用公钥/私钥,等等 我不太了解加密,但我知道我写的任何东西都不会毫无价值。 事实上,我可能会把数学搞乱,让它变得微不足道。

时间:

我清理了 SimpleAES ( 上方上方) 以便我使用。 固定加密/解密方法;对字节缓冲区,字符串和URL-friendly字符串进行编码;已经使用现有库进行URL编码。

代码小,简单,更快,输出更简洁。 例如 johnsmith@gmail.com 生成:


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

代码:


public class SimplerAES
{
 private static byte[] key = { 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 };
 private static byte[] vector = { 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);

标记的变体( 精彩) 应答

  • 添加"使用"
  • 使类成为 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();
 }
 }
}

[EDIT] 年后,我回到了说: 不做 查看加密的错误? ! 的详细信息。

一个非常简单,简单的双向encrytpion是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 ) 另一个时间,将加密的消息与相同的密码( mypassmypassmypass... ) 一起使用。
8 ) 你的消息 !

如果你只想要简单的加密( 例如,可以让一个确定的骇客中断,但锁定大多数临时用户),只需选取两个长度相等的密码句,比如说:


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

并将你的数据与它们的两个( 如有必要,循环使用密码短语) 。 例如:


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

拥有你的binary,有人搜索你的二进制文件可能很好地认为这个实力的方法之一是使用非,但他们可能不会想到C 代码是以外的任何未初始化内存保存。

更新:2015年04月

我将把这个答案留给历史的准确性,但是显然,上面有很多更好的答案。


我发现时标记上面brittingham真正有帮助的回答我在做这个而 .NET 3.5,所以我觉得还是发布我所做的,太。

我跟着标记则指出这个错误,但我用的实例中可用的新AesManaged类. NET 3.5,并采取了利用了ICryptoTransform接口来抽象它放到一个方法中其中的重要部分,即是否这两个大量数据加解密。

交换你自己的密钥和 IV,以及你喜欢的编码方法( 如果你不想使用 Unicode ),你可以:


 public string encryptString(String dataString)
 {
 AesManaged aes = new AesManaged();
 ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
 String encryptedString = performCryptoAndEncoding(dataString, encryptor);
 return encryptedString;
 }

 public string decryptString(String dataString)
 {
 AesManaged aes = new AesManaged();
 ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);
 String decryptedString = performCryptoAndEncoding(dataString, decryptor);
 return decryptedString;
 }

 private string performCryptoAndEncoding(string dataToEncryptOrDecrypt, ICryptoTransform transform)
 {
 byte[] encodedData = encodeStringToBytes(dataToEncryptOrDecrypt);

 MemoryStream dataStream = new MemoryStream();
 CryptoStream encryptionStream = new CryptoStream(dataStream, transform, CryptoStreamMode.Write);

 encryptionStream.Write(encodedData, 0, encodedData.Length);
 encryptionStream.FlushFinalBlock();
 dataStream.Position = 0;

 byte[] transformedBytes = new byte[dataStream.Length];
 dataStream.Read(transformedBytes, 0, transformedBytes.Length);
 encryptionStream.Close();
 dataStream.Close();

 String transformedAndReencodedData = encodeBytesToString(transformedBytes);
 return transformedAndReencodedData;
 }

 private byte[] encodeStringToBytes(string dataToEncode)
 {
 byte[] encodedData = Encoding.Unicode.GetBytes(dataToEncode);
 return encodedData;
 }

 private string encodeBytesToString(byte[] dataToEncode)
 {
 String encodedData = Encoding.Unicode.GetString(dataToEncode, 0, dataToEncode.Length);
 return encodedData;
 }

显然,上面代码中的Unicode编码会中断一些字符。 我想是时候让我进一步了解编码。 下面是一个更多的fail-safe方法,可以从字节 [] 编码/解码到字符串:


 private byte[] encodeStringToBytes(string dataToEncode)
 {
 List<byte> bytes = new List<byte>();
 foreach (char character in dataToEncode.ToCharArray())
 {
 bytes.Add((byte)character);
 }
 return bytes.ToArray();
 }

 private string encodeBytesToString(byte[] dataToEncode)
 {
 String encodedString ="";
 foreach (byte bite in dataToEncode)
 {
 encodedString = encodedString + (char)bite;
 }
 return encodedString;
 }

我更改了 :这个


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

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

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

...