我正在为一些数据寻找非常简单的混淆(比如加密和解密,但不一定安全)功能。这不是关键任务。我需要一些东西来保持诚实的人诚实,但比ROT13或Base64更强大一点。
我更喜欢一些已经包含在. net框架2.0中的东西,这样我就不必担心任何外部依赖。
我真的不想在公钥/私钥等方面浪费时间。我不太懂加密,但我知道我写的任何东西都是没有价值的……事实上,我可能会把数学搞砸,让它变得微不足道。
我正在为一些数据寻找非常简单的混淆(比如加密和解密,但不一定安全)功能。这不是关键任务。我需要一些东西来保持诚实的人诚实,但比ROT13或Base64更强大一点。
我更喜欢一些已经包含在. net框架2.0中的东西,这样我就不必担心任何外部依赖。
我真的不想在公钥/私钥等方面浪费时间。我不太懂加密,但我知道我写的任何东西都是没有价值的……事实上,我可能会把数学搞砸,让它变得微不足道。
当前回答
如果你只是想要简单的加密(即,一个坚定的破解者可能会破解,但会锁定大多数普通用户),只需选择两个长度相等的密码短语,例如:
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)请记住,这是非常简单的加密,根据某些定义,可能根本不被认为是加密(因为加密的目的是防止未经授权的访问,而不仅仅是使其更加困难)。当然,即使是最强的加密也不安全因为有人拿着钢管站在钥匙持有人旁边。
正如第一句所述,这是一种让随意的攻击者变得足够困难的方法,他们会继续前进。这类似于防止入室盗窃——你不需要让它变得坚不可摧,你只需要让它比隔壁的房子不那么坚不可摧:-)
其他回答
我清理了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();
}
}
我改了这个:
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包含TripleDESCryptoServiceProvider类和RijndaelManaged类
不要忘记添加对系统的引用。安全大会。
是,添加系统。安全程序集,导入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);
只是想补充一下,我已经改进了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()
{
// 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");
}