我正在为一些数据寻找非常简单的混淆(比如加密和解密,但不一定安全)功能。这不是关键任务。我需要一些东西来保持诚实的人诚实,但比ROT13或Base64更强大一点。
我更喜欢一些已经包含在. net框架2.0中的东西,这样我就不必担心任何外部依赖。
我真的不想在公钥/私钥等方面浪费时间。我不太懂加密,但我知道我写的任何东西都是没有价值的……事实上,我可能会把数学搞砸,让它变得微不足道。
我正在为一些数据寻找非常简单的混淆(比如加密和解密,但不一定安全)功能。这不是关键任务。我需要一些东西来保持诚实的人诚实,但比ROT13或Base64更强大一点。
我更喜欢一些已经包含在. net框架2.0中的东西,这样我就不必担心任何外部依赖。
我真的不想在公钥/私钥等方面浪费时间。我不太懂加密,但我知道我写的任何东西都是没有价值的……事实上,我可能会把数学搞砸,让它变得微不足道。
当前回答
我想发布我的解决方案,因为上面的解决方案都不像我的那么简单。让我知道你的想法:
// 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)));
}
可选
这里假设用于加密该值的服务器的MachineKey与用于解密该值的MachineKey相同。如果需要,您可以在Web中指定一个静态MachineKey。配置,使您的应用程序可以解密/加密数据,而不管它在哪里运行(例如开发还是生产服务器)。您可以按照这些说明生成一个静态机器密钥。
其他回答
命名空间System.Security.Cryptography包含TripleDESCryptoServiceProvider类和RijndaelManaged类
不要忘记添加对系统的引用。安全大会。
马克斯(优秀)答案的变体
添加“使用” 将类设置为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();
}
}
}
加密很简单:正如其他人指出的那样,在System.Security.Cryptography名称空间中有一些类可以为您完成所有工作。使用它们,而不是任何自制的解决方案。
但是解密也很容易。您遇到的问题不是加密算法,而是保护对用于解密的密钥的访问。
我会使用以下解决方案之一:
DPAPI using the ProtectedData class with CurrentUser scope. This is easy as you don't need to worry about a key. Data can only be decrypted by the same user, so no good for sharing data between users or machines. DPAPI using the ProtectedData class with LocalMachine scope. Good for e.g. protecting configuration data on a single secure server. But anyone who can log into the machine can encrypt it, so no good unless the server is secure. Any symmetric algorithm. I typically use the static SymmetricAlgorithm.Create() method if I don't care what algorithm is used (in fact it's Rijndael by default). In this case you need to protect your key somehow. E.g. you can obfuscate it in some way and hide it in your code. But be aware that anyone who is smart enough to decompile your code will likely be able to find the key.
我想发布我的解决方案,因为上面的解决方案都不像我的那么简单。让我知道你的想法:
// 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)));
}
可选
这里假设用于加密该值的服务器的MachineKey与用于解密该值的MachineKey相同。如果需要,您可以在Web中指定一个静态MachineKey。配置,使您的应用程序可以解密/加密数据,而不管它在哪里运行(例如开发还是生产服务器)。您可以按照这些说明生成一个静态机器密钥。
使用内置的. 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;
}
}
}