.NET下的原始RSA加密(又名ECB / NoPadding)?

时间:2016-06-12 19:14:47

标签: c# .net cryptography rsa

我认为.NET(使用C#)在不直接支持的标准RSA签名方案的验证部分下的可行性和性能。为实现这一目标,我需要原始RSA公钥加密函数 x→(x 65537 )mod N (其中 x 是一个字节数组与公共模数 N 一样宽,如256字节)。

在其他平台上,标准技术是使用没有填充的RSA加密来实现该功能(Java" RSA / ECB / NoPadding")。但我无法在.NET下找到如何执行此操作。我有什么选择?

1 个答案:

答案 0 :(得分:1)

.NET不提供此功能收件箱。如果您只是在进行公钥操作,那么您可以使用BigInteger类而无需承担安全责任。 (不要将它用于私钥操作,因为a)它会在内存中明显地显示你的私钥,b)它没有基于蒙哥马利梯形图的ModPow,所以它会泄漏私钥的汉明重量)

RSA existingKey = HoweverYouWereGettingAKey();
RSAParameters rsaParams = existingKey.ExportParameters(false);

BigInteger n = PrepareBigInteger(rsaParams.Modulus);
BigInteger e = PrepareBigInteger(rsaParams.Exponent);
BigInteger sig = PrepareBigInteger(signature);
BigInteger paddedMsgVal = BigInteger.ModPow(sig, e, n);

byte[] paddedMsg = paddedMsgVal.ToArray();

if (paddedMsg[paddedMsg.Length - 1] == 0)
{
    Array.Resize(ref paddedMsg, paddedMsg.Length - 1);
}

Array.Reverse(paddedMsg);
// paddedMsg is now ready.

private static BigInteger PrepareBigInteger(byte[] unsignedBigEndian)
{
    // Leave an extra 0x00 byte so that the sign bit is clear
    byte[] tmp = new byte[unsignedBigEndian.Length + 1];
    Buffer.BlockCopy(unsignedBigEndian, 0, tmp, 1, unsignedBigInteger.Length);
    Array.Reverse(tmp);
    return new BigInteger(tmp);
}