2,非对称加密和解密
私钥加密m(二进制表示)时,首先把m分成长s的数据块 m1, m2 ... mi,其中 2^s <= n, s 尽可能的大。执行如下计算:
ci = mi ^ d (mod n)
公钥解密c(二进制表示)时,也需要将c分成长s的数据块c1, c2 ... ci,执行如下计算:
mi = ci ^ e (mod n)
在某些情况下,也会使用公钥加密->私钥解密。原理和私钥加密->公钥解密一样。下面是私钥计算和公钥计算的算法。其中利用到了Chew Keong TAN的BigInteger类。.NET Framework 4中提供的BigInteger.ModPow方法好像有问题。
private static byte[] Compute(byte[] data, RSAPublicKey publicKey, int blockSize)
{
//
// 公钥加密/解密公式为:ci = mi^e ( mod n )
//
// 先将 m(二进制表示)分成数据块 m1, m2, ..., mi ,然后进行运算。
//
BigInteger e = new BigInteger(publicKey.Exponent);
BigInteger n = new BigInteger(publicKey.Modulus);
int blockOffset = 0;
using (MemoryStream stream = new MemoryStream())
{
while (blockOffset < data.Length)
{
int blockLen = Math.Min(blockSize, data.Length - blockOffset);
byte[] blockData = new byte[blockLen];
Buffer.BlockCopy(data, blockOffset, blockData, 0, blockLen);
BigInteger mi = new BigInteger(blockData);
BigInteger ci = mi.modPow(e, n);//ci = mi^e ( mod n )
byte[] block = ci.getBytes();
stream.Write(block, 0, block.Length);
blockOffset += blockLen;
}
return stream.ToArray();
}
}
private static byte[] Compute(byte[] data, RSAPrivateKey privateKey, int blockSize)
{
//
// 私钥加密/解密公式为:mi = ci^d ( mod n )
//
// 先将 c(二进制表示)分成数据块 c1, c2, ..., ci ,然后进行运算。
//
BigInteger d = new BigInteger(privateKey.D);
BigInteger n = new BigInteger(privateKey.Modulus);
int blockOffset = 0;
using (MemoryStream stream = new MemoryStream())
{
while (blockOffset < data.Length)
{
int blockLen = Math.Min(blockSize, data.Length - blockOffset);
byte[] blockData = new byte[blockLen];
Buffer.BlockCopy(data, blockOffset, blockData, 0, blockLen);
BigInteger ci = new BigInteger(blockData);
BigInteger mi = ci.modPow(d, n);//mi = ci^d ( mod n )
byte[] block = mi.getBytes();
stream.Write(block, 0, block.Length);
blockOffset += blockLen;
}
return stream.ToArray();
}
}
下面是私钥加密->公钥解密的实现。
public static byte[] Encrypt(byte[] data, RSAPublicKey publicKey)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (publicKey == null)
{
throw new ArgumentNullException("publicKey");
}
int blockSize = publicKey.Modulus.Length - 1;
return Compute(data, publicKey, blockSize);
}
public static byte[] Decrypt(byte[] data, RSAPrivateKey privateKey)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (privateKey == null)
{
throw new ArgumentNullException("privateKey");
}
int blockSize = privateKey.Modulus.Length;
return Compute(data, privateKey, blockSize);
}
下面是公钥加密->私钥解密的实现。
public static byte[] Encrypt(byte[] data, RSAPrivateKey privateKey)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (privateKey == null)
{
throw new ArgumentNullException("privateKey");
}
int blockSize = privateKey.Modulus.Length - 1;
return Compute(data, privateKey, blockSize);
}
public static byte[] Decrypt(byte[] data, RSAPublicKey publicKey)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (publicKey == null)
{
throw new ArgumentNullException("publicKey");
}
int blockSize = publicKey.Modulus.Length;
return Compute(data, publicKey, blockSize);
}


