Pkcs5S2ParametersGenerator.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  11. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
  12. {
  13. /**
  14. * Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 2.
  15. * This generator uses a SHA-1 HMac as the calculation function.
  16. * <p>
  17. * The document this implementation is based on can be found at
  18. * <a href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html">
  19. * RSA's Pkcs5 Page</a></p>
  20. */
  21. public class Pkcs5S2ParametersGenerator
  22. : PbeParametersGenerator
  23. {
  24. private readonly IMac hMac;
  25. private readonly byte[] state;
  26. /**
  27. * construct a Pkcs5 Scheme 2 Parameters generator.
  28. */
  29. public Pkcs5S2ParametersGenerator()
  30. : this(new Sha1Digest())
  31. {
  32. }
  33. public Pkcs5S2ParametersGenerator(IDigest digest)
  34. {
  35. this.hMac = new HMac(digest);
  36. this.state = new byte[hMac.GetMacSize()];
  37. }
  38. private void F(
  39. byte[] S,
  40. int c,
  41. byte[] iBuf,
  42. byte[] outBytes,
  43. int outOff)
  44. {
  45. if (c == 0)
  46. throw new ArgumentException("iteration count must be at least 1.");
  47. if (S != null)
  48. {
  49. hMac.BlockUpdate(S, 0, S.Length);
  50. }
  51. hMac.BlockUpdate(iBuf, 0, iBuf.Length);
  52. hMac.DoFinal(state, 0);
  53. Array.Copy(state, 0, outBytes, outOff, state.Length);
  54. for (int count = 1; count < c; ++count)
  55. {
  56. hMac.BlockUpdate(state, 0, state.Length);
  57. hMac.DoFinal(state, 0);
  58. for (int j = 0; j < state.Length; ++j)
  59. {
  60. outBytes[outOff + j] ^= state[j];
  61. }
  62. }
  63. }
  64. private byte[] GenerateDerivedKey(
  65. int dkLen)
  66. {
  67. int hLen = hMac.GetMacSize();
  68. int l = (dkLen + hLen - 1) / hLen;
  69. byte[] iBuf = new byte[4];
  70. byte[] outBytes = new byte[l * hLen];
  71. int outPos = 0;
  72. ICipherParameters param = new KeyParameter(mPassword);
  73. hMac.Init(param);
  74. for (int i = 1; i <= l; i++)
  75. {
  76. // Increment the value in 'iBuf'
  77. int pos = 3;
  78. while (++iBuf[pos] == 0)
  79. {
  80. --pos;
  81. }
  82. F(mSalt, mIterationCount, iBuf, outBytes, outPos);
  83. outPos += hLen;
  84. }
  85. return outBytes;
  86. }
  87. /**
  88. * Generate a key parameter derived from the password, salt, and iteration
  89. * count we are currently initialised with.
  90. *
  91. * @param keySize the size of the key we want (in bits)
  92. * @return a KeyParameter object.
  93. */
  94. public override ICipherParameters GenerateDerivedParameters(
  95. int keySize)
  96. {
  97. return GenerateDerivedMacParameters(keySize);
  98. }
  99. public override ICipherParameters GenerateDerivedParameters(
  100. string algorithm,
  101. int keySize)
  102. {
  103. keySize /= 8;
  104. byte[] dKey = GenerateDerivedKey(keySize);
  105. return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
  106. }
  107. /**
  108. * Generate a key with initialisation vector parameter derived from
  109. * the password, salt, and iteration count we are currently initialised
  110. * with.
  111. *
  112. * @param keySize the size of the key we want (in bits)
  113. * @param ivSize the size of the iv we want (in bits)
  114. * @return a ParametersWithIV object.
  115. */
  116. public override ICipherParameters GenerateDerivedParameters(
  117. int keySize,
  118. int ivSize)
  119. {
  120. keySize /= 8;
  121. ivSize /= 8;
  122. byte[] dKey = GenerateDerivedKey(keySize + ivSize);
  123. return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
  124. }
  125. public override ICipherParameters GenerateDerivedParameters(
  126. string algorithm,
  127. int keySize,
  128. int ivSize)
  129. {
  130. keySize /= 8;
  131. ivSize /= 8;
  132. byte[] dKey = GenerateDerivedKey(keySize + ivSize);
  133. KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
  134. return new ParametersWithIV(key, dKey, keySize, ivSize);
  135. }
  136. /**
  137. * Generate a key parameter for use with a MAC derived from the password,
  138. * salt, and iteration count we are currently initialised with.
  139. *
  140. * @param keySize the size of the key we want (in bits)
  141. * @return a KeyParameter object.
  142. */
  143. public override ICipherParameters GenerateDerivedMacParameters(
  144. int keySize)
  145. {
  146. keySize /= 8;
  147. byte[] dKey = GenerateDerivedKey(keySize);
  148. return new KeyParameter(dKey, 0, keySize);
  149. }
  150. }
  151. }
  152. #pragma warning restore
  153. #endif