我正在实施一个简短的RSA程序并拥有以下代码:
private string Encrypt(string data)
{
BigInteger dataAsBigInteger = new BigInteger(Encoding.UTF8.GetBytes(data));
BigInteger remainder = BigInteger.ModPow(dataAsBigInteger, exponentE, CalculatePublicKey());
return Convert.ToBase64String(remainder.ToByteArray());
}
private string Decrypt(string data)
{
BigInteger dataAsBigInteger = new BigInteger(Convert.FromBase64String(data));
BigInteger remainder = BigInteger.ModPow(dataAsBigInteger, CalculatePrivateKey(), CalculatePublicKey());
return Encoding.UTF8.GetString(remainder.ToByteArray());
}
不幸的是,我似乎得到了结果的奇怪的ASCII值。我尝试使用数字而不是文本和Decrypt(Encrypt(number)) == number
所以我知道算法很好,所以我认为它是乱码,因为转换为字节数组和从字节数组执行操作。
如果这不起作用,我想更好地考虑将字母转换为数字的公式。我不能A = 1, B = 2, etc.
,因为11与K (11th letter)
不明确。也许如果每个字母的位置(A = 1, B = 2, etc.)
首先乘以10,那么你会知道下一个字母是从一个非零值开始的吗?
这样的事情是可取的还是可以挽救字节数组?
答案 0 :(得分:2)
原则上您的方案应该有效,只要结果BigInteger
不是负数或大于模数。
如果使用加密安全的RSA实现(如OAEP),则还需要减去填充的开销。通常,您应该只加密对称密钥,并使用hybrid cryptography来允许几乎任意的邮件大小。
答案 1 :(得分:-1)
你要做的事情没有意义。 RSA只能加密固定长度消息,与公共模数 n 具有相同数量级的整数。 (具体来说,如果明文 m ,作为一个数字,足够小, m e < n ,那么加密是平凡可逆的,如果它大于 n n ,则根本无法加密。)
此外,您似乎正在尝试实施“textbook RSA”,这是不安全。您需要重新设计应用程序,以便将RSA用作key encapsulation方案的一部分,该方案可安全地提供对称(例如AES)密钥,该密钥在authenticated operation mode中用于加密实际的消息。
对您的设计进行此更正也会使您的编码问题失败,因为现在正在使用对比密码加密正确的消息,该密码对比特流而不是数字进行操作。
如果C#没有为您执行此操作的库,我会非常惊讶。