RSABlindedEngine.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Crypto.Parameters;
  4. using Org.BouncyCastle.Math;
  5. using Org.BouncyCastle.Security;
  6. using Org.BouncyCastle.Utilities;
  7. namespace Org.BouncyCastle.Crypto.Engines
  8. {
  9. /**
  10. * this does your basic RSA algorithm with blinding
  11. */
  12. public class RsaBlindedEngine
  13. : IAsymmetricBlockCipher
  14. {
  15. private readonly RsaCoreEngine core = new RsaCoreEngine();
  16. private RsaKeyParameters key;
  17. private SecureRandom random;
  18. public virtual string AlgorithmName
  19. {
  20. get { return "RSA"; }
  21. }
  22. /**
  23. * initialise the RSA engine.
  24. *
  25. * @param forEncryption true if we are encrypting, false otherwise.
  26. * @param param the necessary RSA key parameters.
  27. */
  28. public virtual void Init(
  29. bool forEncryption,
  30. ICipherParameters param)
  31. {
  32. core.Init(forEncryption, param);
  33. if (param is ParametersWithRandom)
  34. {
  35. ParametersWithRandom rParam = (ParametersWithRandom)param;
  36. key = (RsaKeyParameters)rParam.Parameters;
  37. random = rParam.Random;
  38. }
  39. else
  40. {
  41. key = (RsaKeyParameters)param;
  42. random = new SecureRandom();
  43. }
  44. }
  45. /**
  46. * Return the maximum size for an input block to this engine.
  47. * For RSA this is always one byte less than the key size on
  48. * encryption, and the same length as the key size on decryption.
  49. *
  50. * @return maximum size for an input block.
  51. */
  52. public virtual int GetInputBlockSize()
  53. {
  54. return core.GetInputBlockSize();
  55. }
  56. /**
  57. * Return the maximum size for an output block to this engine.
  58. * For RSA this is always one byte less than the key size on
  59. * decryption, and the same length as the key size on encryption.
  60. *
  61. * @return maximum size for an output block.
  62. */
  63. public virtual int GetOutputBlockSize()
  64. {
  65. return core.GetOutputBlockSize();
  66. }
  67. /**
  68. * Process a single block using the basic RSA algorithm.
  69. *
  70. * @param inBuf the input array.
  71. * @param inOff the offset into the input buffer where the data starts.
  72. * @param inLen the length of the data to be processed.
  73. * @return the result of the RSA process.
  74. * @exception DataLengthException the input block is too large.
  75. */
  76. public virtual byte[] ProcessBlock(
  77. byte[] inBuf,
  78. int inOff,
  79. int inLen)
  80. {
  81. if (key == null)
  82. throw new InvalidOperationException("RSA engine not initialised");
  83. BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
  84. BigInteger result;
  85. if (key is RsaPrivateCrtKeyParameters)
  86. {
  87. RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key;
  88. BigInteger e = k.PublicExponent;
  89. if (e != null) // can't do blinding without a public exponent
  90. {
  91. BigInteger m = k.Modulus;
  92. BigInteger r = BigIntegers.CreateRandomInRange(
  93. BigInteger.One, m.Subtract(BigInteger.One), random);
  94. BigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m);
  95. BigInteger blindedResult = core.ProcessBlock(blindedInput);
  96. BigInteger rInv = r.ModInverse(m);
  97. result = blindedResult.Multiply(rInv).Mod(m);
  98. // defence against Arjen Lenstra’s CRT attack
  99. if (!input.Equals(result.ModPow(e, m)))
  100. throw new InvalidOperationException("RSA engine faulty decryption/signing detected");
  101. }
  102. else
  103. {
  104. result = core.ProcessBlock(input);
  105. }
  106. }
  107. else
  108. {
  109. result = core.ProcessBlock(input);
  110. }
  111. return core.ConvertOutput(result);
  112. }
  113. }
  114. }
  115. #endif