【问题标题】:How to encrypt a byte array using own RSA encryption?如何使用自己的 RSA 加密来加密字节数组?
【发布时间】:2013-12-22 23:16:07
【问题描述】:

我正在尝试制作自己的 RSA 加密。我知道 C# 中有内置方法,但我想制作自己的程序,因为我想了解它是如何完成的。我想我在转换字节数组时搞砸了。如果有人能把我推向正确的方向,那就太好了:)。

private void btnEncrypt_Click(object sender, EventArgs e)
{
    EncryptieModulo = 55;
    PublicKey = 27;
    var PlainText = Encoding.UTF8.GetBytes(txtPlaintext.Text);
    for (int i = 0; i < PlainText.Length; i++)
    {
        PlainText[i] = (byte)(BigInteger.Pow(PlainText[i], PublicKey) % EncryptieModulo);
    }

    textBox1.Text = Convert.ToBase64String(PlainText);
}

private void btnDecrypt_Click(object sender, EventArgs e)
{
    EncryptieModulo = 55;
    PrivateKey = 3;
    var CrypText = Convert.FromBase64String(txtCCryptedText.Text);
    for (int i = 0; i < CrypText.Length; i++)
    {
        CrypText[i] = (byte)(BigInteger.Pow(CrypText[i], PrivateKey) % EncryptieModulo);
    }

    textBox1.Text = Encoding.UTF8.GetString(CrypText);
}

【问题讨论】:

  • 请通过示例输入和输出解释这段代码的作用,并解释它应该做什么以及您尝试调查这些差异的原因。
  • 当我加密字符串“Pablo”时,它返回“FDAgJQE="。现在,当我尝试解密它时,它会返回字符串“*+5”。
  • @CodeCaster:从代码中我可以看出,他正在尝试实现非常基本的 RSA 以了解其工作原理。或多或少在这里描述的en.wikipedia.org/wiki/RSA_%28cryptosystem%29#A_working_example 基于此emc.com/emc-plus/rsa-labs/pkcs/files/… 的完整实现不会那么简单,但他只是试图以最基本的形式解决 RSA 的内部工作原理。
  • 是的,谢谢 zespri,这就是我想要做的。
  • 只需坚持使用字节数组进行加密/解密方法并让该部分正常工作。比弄清楚你的 string->byte->string 序列是否/为什么被破坏。

标签: c# arrays byte rsa


【解决方案1】:

您编码的值必须小于模数,在您的情况下为 55。为了使您的示例正常工作,您需要用将拉丁字母字符转换为的自定义函数替换 Encoding.UTF8.GetBytes/Encoding.UTF8.GetString 0-54 之间的字节数。

例如你可以这样做:

private static byte[] GetBytes(string s)
{
    byte[] result = new byte[s.Length];
    for (int i = 0; i < s.Length; i++)
    {
        if (s[i] >= 'a' && s[i] <= 'z')
        {
            result[i] = (byte)(s[i] - 'a');
            continue;
        }
        if (s[i] >= 'A' && s[i] <= 'Z')
        {
            result[i] = (byte)(s[i] - 'A' + 26);
            continue;
        }
        throw new ArgumentOutOfRangeException();
    }
    return result;
}

private static string GetString(byte[] b)
{
    StringBuilder sb = new StringBuilder(b.Length);
    for (int i = 0; i < b.Length; i++)
    {
        if (b[i] >= 0 && b[i] < 26)
        {
            sb.Append((char)('a' + b[i]));
            continue;
        }
        if (b[i] >= 26 && b[i] < 52)
        {
            sb.Append((char)('A' + b[i] - 26));
            continue;
        }
        throw new ArgumentOutOfRangeException();
    }
    return sb.ToString();
}

现在用我们的新Encoding.UTF8.GetBytes/Encoding.UTF8.GetString 替换你的Encoding.UTF8.GetString,你应该很高兴。

注意不过,您刚刚所做的并不是真正的 RSA 加密。您只需使用非常短的密钥单独加密每个字节。这个实现的安全性是 zilch。请参阅the spec 了解“真实”实现的所有复杂性。 (想到一个填充)。此外,如果您想更好地理解算法,我建议您查找一些真实的开源实现。

【讨论】:

  • 谢谢,这真的很有帮助。除了非常短的密钥,还有其他不安全的原因吗?
  • 是的。你最好在crypto.stackexchange.com 上问这个问题,但一般来说,如果你使用任何给定的密钥逐字节加密,每个字节只会得到 256 个不同的输出,并且输出和字节之间会有一对一的映射。也就是说,每个 0x01 将始终加密为 0x5fa3dd。我希望你能看到这有多糟糕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多