使用较小的结果字符串进行简单的字符串加密/解密

时间:2012-11-08 19:46:34

标签: c# encryption

我需要加密字符串然后再次解密。

我实现了解决方案here并且效果很好,但结果字符串不合适,因为它需要简单且足够短以供用户使用。

我正在加密递增数据库ID(从1开始),并且不会超过500.理想情况下,我希望加密字符串的长度不超过6个字符。

任何想法都赞赏..

编辑:这是一个冗长的表单,用户可以在以后使用此生成的字符串恢复

4 个答案:

答案 0 :(得分:6)

您可以在CTR mode中使用AES而无需任何填充。在这种模式下,有一个加密的计数器,然后结果与你的明文xor'd,这是数字。结果应该很小,你将获得AES的加密,这将比你使用的任何替换密码(你可能可以手动破解)更好。但是,由于Microsoft BouncyCastle crypto library的实施没有将CTR作为Rijndael,因此您必须获得available mode。下面是您需要实现的AES类的示例。以及加密和解密的一个例子。

using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;

public class AES
{
    private readonly Encoding encoding;

    private SicBlockCipher mode;


    public AES(Encoding encoding)
    {
        this.encoding = encoding;
        this.mode = new SicBlockCipher(new AesFastEngine());
    }

    public static string ByteArrayToString(byte[] bytes)
    {
        return BitConverter.ToString(bytes).Replace("-", string.Empty);
    }

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


    public string Encrypt(string plain, byte[] key, byte[] iv)
    {
        byte[] input = this.encoding.GetBytes(plain);

        byte[] bytes = this.BouncyCastleCrypto(true, input, key, iv);

        string result = ByteArrayToString(bytes);

        return result;
    }


    public string Decrypt(string cipher, byte[] key, byte[] iv)
    {
        byte[] bytes = this.BouncyCastleCrypto(false, StringToByteArray(cipher), key, iv);

        string result = this.encoding.GetString(bytes);

        return result;
    }


    private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, byte[] key, byte[] iv)
    {
        try
        {
            this.mode.Init(forEncrypt, new ParametersWithIV(new KeyParameter(key), iv));

            BufferedBlockCipher cipher = new BufferedBlockCipher(this.mode);

            return cipher.DoFinal(input);
        }
        catch (CryptoException)
        {
            throw;
        }
    }
}

使用示例

string test = "1";

AES aes = new AES(System.Text.Encoding.UTF8);

RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
byte[] key = new byte[32];
byte[] iv = new byte[32];

// Generate random key and IV
rngCsp.GetBytes(key);
rngCsp.GetBytes(iv);

string cipher = aes.Encrypt(test, key, iv);

string plaintext = aes.Decrypt(cipher, key, iv);

Response.Write(cipher + "<BR/>");

Response.Write(plaintext);

输出示例

CB
1 

答案 1 :(得分:3)

//encryption   
string output="";   
char[] readChar = yourInput.ToCharArray();   
for (int i = 0; i < readChar.Length; i++)  
{   
    int no = Convert.ToInt32(readChar[i]) + 10;   
    string r = Convert.ToChar(no).ToString();   
    output+=r;   
}  
//decryption  
string output="";   
char[] readChar = yourInput.ToCharArray();   
for (int i = 0; i < readChar.Length; i++)   
{   
    int no = Convert.ToInt32(readChar[i]) - 10;   
    string r = Convert.ToChar(no).ToString();   
    output+=r;   
}

答案 2 :(得分:1)

如果你想要简单,可以使用6个字母的主键 将它添加到6个字母输入中,根据允许的输入字符进行模数

就像a = 1

b = 2

c = 3

然后简单地添加数字a + 13 mod 24&gt; ...

不会说它的安全,但它的简单,如你所要求的 你也可以做一些组合,比如下一个char是deoded prev char为+ xx

答案 3 :(得分:0)

既然你说这些是递增的数据库ID我假设我们正在讨论正整数。限制加密确实不是一个好主意,因为加密越有限,就越容易破解。我不确定你的目标,但听起来你可能只想通过“加密”来隐藏最终用户的ID。所以,如果我假设这些是1到999之间的正整数,那么我的建议如下。一,简单的字符替换。很容易理解,因为你将限制在10个字符以内。二,将它们转换为十六进制。不会欺骗很多人,但普通的最终用户可能无法识别它。第三,将数字转换为Base64。这不像十六进制那样容易识别。最后,提出一些公式,您可以应用于始终产生独特结果的数字。我真的不建议,但是因为它很难。