CryptoApiEntropySourceProvider.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Security.Cryptography;
  5. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng
  6. {
  7. public class CryptoApiEntropySourceProvider
  8. : IEntropySourceProvider
  9. {
  10. private readonly RandomNumberGenerator mRng;
  11. private readonly bool mPredictionResistant;
  12. public CryptoApiEntropySourceProvider()
  13. : this(RandomNumberGenerator.Create(), true)
  14. {
  15. }
  16. public CryptoApiEntropySourceProvider(RandomNumberGenerator rng, bool isPredictionResistant)
  17. {
  18. if (rng == null)
  19. throw new ArgumentNullException("rng");
  20. mRng = rng;
  21. mPredictionResistant = isPredictionResistant;
  22. }
  23. public IEntropySource Get(int bitsRequired)
  24. {
  25. return new CryptoApiEntropySource(mRng, mPredictionResistant, bitsRequired);
  26. }
  27. private class CryptoApiEntropySource
  28. : IEntropySource
  29. {
  30. private readonly RandomNumberGenerator mRng;
  31. private readonly bool mPredictionResistant;
  32. private readonly int mEntropySize;
  33. internal CryptoApiEntropySource(RandomNumberGenerator rng, bool predictionResistant, int entropySize)
  34. {
  35. this.mRng = rng;
  36. this.mPredictionResistant = predictionResistant;
  37. this.mEntropySize = entropySize;
  38. }
  39. #region IEntropySource Members
  40. bool IEntropySource.IsPredictionResistant
  41. {
  42. get { return mPredictionResistant; }
  43. }
  44. byte[] IEntropySource.GetEntropy()
  45. {
  46. byte[] result = new byte[(mEntropySize + 7) / 8];
  47. mRng.GetBytes(result);
  48. return result;
  49. }
  50. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  51. int IEntropySource.GetEntropy(Span<byte> output)
  52. {
  53. int length = (mEntropySize + 7) / 8;
  54. mRng.GetBytes(output[..length]);
  55. return length;
  56. }
  57. #endif
  58. int IEntropySource.EntropySize
  59. {
  60. get { return mEntropySize; }
  61. }
  62. #endregion
  63. }
  64. }
  65. }
  66. #pragma warning restore
  67. #endif