RSACipher.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Security.Cryptography;
  6. using Renci.SshNet.Common;
  7. namespace Renci.SshNet.Security.Cryptography
  8. {
  9. public class RSACipher : AsymmetricCipher
  10. {
  11. private static RNGCryptoServiceProvider _randomizer = new System.Security.Cryptography.RNGCryptoServiceProvider();
  12. private RSAPublicKey _key;
  13. public RSACipher(HashAlgorithm hash, RSAPublicKey key)
  14. {
  15. this._key = key;
  16. }
  17. public override byte[] Transform(byte[] data)
  18. {
  19. var bytes = new List<byte>(data.Reverse());
  20. bytes.Add(0);
  21. return this.Transform(new BigInteger(bytes.ToArray())).ToByteArray().Reverse().ToArray();
  22. }
  23. public override BigInteger Transform(BigInteger input)
  24. {
  25. var privateKey = this._key as RSAPrivateKey;
  26. if (privateKey != null)
  27. {
  28. BigInteger random = BigInteger.One;
  29. var max = this._key.Modulus - 1;
  30. while (random <= BigInteger.One || random >= max)
  31. {
  32. var bytesArray = new byte[256];
  33. _randomizer.GetBytes(bytesArray);
  34. bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value
  35. random = new BigInteger(bytesArray.Reverse().ToArray());
  36. }
  37. BigInteger blindedInput = BigInteger.PositiveMod((BigInteger.ModPow(random, this._key.Exponent, this._key.Modulus) * input), this._key.Modulus);
  38. // mP = ((input Mod p) ^ dP)) Mod p
  39. var mP = BigInteger.ModPow((blindedInput % privateKey.P), privateKey.DP, privateKey.P);
  40. // mQ = ((input Mod q) ^ dQ)) Mod q
  41. var mQ = BigInteger.ModPow((blindedInput % privateKey.Q), privateKey.DQ, privateKey.Q);
  42. var h = BigInteger.PositiveMod(((mP - mQ) * privateKey.InverseQ), privateKey.P);
  43. var m = h * privateKey.Q + mQ;
  44. BigInteger rInv = BigInteger.ModInverse(random, this._key.Modulus);
  45. return BigInteger.PositiveMod((m * rInv), this._key.Modulus);
  46. }
  47. else
  48. {
  49. var value = BigInteger.ModPow(input, this._key.Exponent, this._key.Modulus);
  50. return value;
  51. }
  52. }
  53. }
  54. }