RSABlindingEngine.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  8. {
  9. /**
  10. * This does your basic RSA Chaum's blinding and unblinding as outlined in
  11. * "Handbook of Applied Cryptography", page 475. You need to use this if you are
  12. * trying to get another party to generate signatures without them being aware
  13. * of the message they are signing.
  14. */
  15. public class RsaBlindingEngine
  16. : IAsymmetricBlockCipher
  17. {
  18. private readonly IRsa core;
  19. private RsaKeyParameters key;
  20. private BigInteger blindingFactor;
  21. private bool forEncryption;
  22. public RsaBlindingEngine()
  23. : this(new RsaCoreEngine())
  24. {
  25. }
  26. public RsaBlindingEngine(IRsa rsa)
  27. {
  28. this.core = rsa;
  29. }
  30. public virtual string AlgorithmName
  31. {
  32. get { return "RSA"; }
  33. }
  34. /**
  35. * Initialise the blinding engine.
  36. *
  37. * @param forEncryption true if we are encrypting (blinding), false otherwise.
  38. * @param param the necessary RSA key parameters.
  39. */
  40. public virtual void Init(
  41. bool forEncryption,
  42. ICipherParameters param)
  43. {
  44. RsaBlindingParameters p;
  45. if (param is ParametersWithRandom)
  46. {
  47. ParametersWithRandom rParam = (ParametersWithRandom)param;
  48. p = (RsaBlindingParameters)rParam.Parameters;
  49. }
  50. else
  51. {
  52. p = (RsaBlindingParameters)param;
  53. }
  54. core.Init(forEncryption, p.PublicKey);
  55. this.forEncryption = forEncryption;
  56. this.key = p.PublicKey;
  57. this.blindingFactor = p.BlindingFactor;
  58. }
  59. /**
  60. * Return the maximum size for an input block to this engine.
  61. * For RSA this is always one byte less than the key size on
  62. * encryption, and the same length as the key size on decryption.
  63. *
  64. * @return maximum size for an input block.
  65. */
  66. public virtual int GetInputBlockSize()
  67. {
  68. return core.GetInputBlockSize();
  69. }
  70. /**
  71. * Return the maximum size for an output block to this engine.
  72. * For RSA this is always one byte less than the key size on
  73. * decryption, and the same length as the key size on encryption.
  74. *
  75. * @return maximum size for an output block.
  76. */
  77. public virtual int GetOutputBlockSize()
  78. {
  79. return core.GetOutputBlockSize();
  80. }
  81. /**
  82. * Process a single block using the RSA blinding algorithm.
  83. *
  84. * @param in the input array.
  85. * @param inOff the offset into the input buffer where the data starts.
  86. * @param inLen the length of the data to be processed.
  87. * @return the result of the RSA process.
  88. * @throws DataLengthException the input block is too large.
  89. */
  90. public virtual byte[] ProcessBlock(
  91. byte[] inBuf,
  92. int inOff,
  93. int inLen)
  94. {
  95. BigInteger msg = core.ConvertInput(inBuf, inOff, inLen);
  96. if (forEncryption)
  97. {
  98. msg = BlindMessage(msg);
  99. }
  100. else
  101. {
  102. msg = UnblindMessage(msg);
  103. }
  104. return core.ConvertOutput(msg);
  105. }
  106. /*
  107. * Blind message with the blind factor.
  108. */
  109. private BigInteger BlindMessage(
  110. BigInteger msg)
  111. {
  112. BigInteger blindMsg = blindingFactor;
  113. blindMsg = msg.Multiply(blindMsg.ModPow(key.Exponent, key.Modulus));
  114. blindMsg = blindMsg.Mod(key.Modulus);
  115. return blindMsg;
  116. }
  117. /*
  118. * Unblind the message blinded with the blind factor.
  119. */
  120. private BigInteger UnblindMessage(
  121. BigInteger blindedMsg)
  122. {
  123. BigInteger m = key.Modulus;
  124. BigInteger msg = blindedMsg;
  125. BigInteger blindFactorInverse = BigIntegers.ModOddInverse(m, blindingFactor);
  126. msg = msg.Multiply(blindFactorInverse);
  127. msg = msg.Mod(m);
  128. return msg;
  129. }
  130. }
  131. }
  132. #pragma warning restore
  133. #endif