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