You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CryptoUtils.cs 1.7 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using CryptoBase.Digests.MD5;
  2. using System;
  3. using System.Buffers;
  4. using System.Text;
  5. namespace Shadowsocks.Protocol.Shadowsocks.Crypto
  6. {
  7. public static class CryptoUtils
  8. {
  9. public static byte[] SSKDF(string password, int keylen)
  10. {
  11. const int md5Length = 16;
  12. var pwMaxSize = Encoding.UTF8.GetMaxByteCount(password.Length);
  13. var key = new byte[keylen];
  14. var pwBuffer = ArrayPool<byte>.Shared.Rent(pwMaxSize);
  15. var resultBuffer = ArrayPool<byte>.Shared.Rent(pwMaxSize + md5Length);
  16. try
  17. {
  18. var pwLength = Encoding.UTF8.GetBytes(password, pwBuffer);
  19. var pw = pwBuffer.AsSpan(0, pwLength);
  20. Span<byte> md5Sum = stackalloc byte[md5Length];
  21. var result = resultBuffer.AsSpan(0, pwLength + md5Length);
  22. var i = 0;
  23. while (i < keylen)
  24. {
  25. if (i == 0)
  26. {
  27. MD5Utils.Default(pw, md5Sum);
  28. }
  29. else
  30. {
  31. md5Sum.CopyTo(result);
  32. pw.CopyTo(result.Slice(md5Length));
  33. MD5Utils.Default(result, md5Sum);
  34. }
  35. var length = Math.Min(16, keylen - i);
  36. md5Sum.Slice(0, length).CopyTo(key.AsSpan(i, length));
  37. i += md5Length;
  38. }
  39. return key;
  40. }
  41. finally
  42. {
  43. ArrayPool<byte>.Shared.Return(pwBuffer);
  44. ArrayPool<byte>.Shared.Return(resultBuffer);
  45. }
  46. }
  47. }
  48. }