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.

StreamNativeEncryptor.cs 2.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace Shadowsocks.Encryption.Stream
  7. {
  8. public class StreamNativeEncryptor : StreamEncryptor
  9. {
  10. bool md5;
  11. byte[] realkey;
  12. byte[] sbox;
  13. public StreamNativeEncryptor(string method, string password) : base(method, password)
  14. {
  15. md5 = method.ToLowerInvariant().IndexOf("md5") >= 0;
  16. }
  17. public override void Dispose()
  18. {
  19. return;
  20. }
  21. protected override void initCipher(byte[] iv, bool isEncrypt)
  22. {
  23. base.initCipher(iv, isEncrypt);
  24. if (md5)
  25. {
  26. byte[] temp = new byte[keyLen + ivLen];
  27. Array.Copy(_key, 0, temp, 0, keyLen);
  28. Array.Copy(iv, 0, temp, keyLen, ivLen);
  29. realkey = MbedTLS.MD5(temp);
  30. }
  31. else
  32. {
  33. realkey = _key;
  34. }
  35. sbox = EncryptInitalize(realkey);
  36. }
  37. protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
  38. {
  39. var ctx = isEncrypt ? enc_ctx : dec_ctx;
  40. byte[] t = new byte[length];
  41. Array.Copy(buf, t, length);
  42. EncryptOutput(ctx, sbox, t, length);
  43. Array.Copy(t, outbuf, length);
  44. }
  45. protected override Dictionary<string, EncryptorInfo> getCiphers()
  46. {
  47. return new Dictionary<string, EncryptorInfo>()
  48. {
  49. { "rc4-md5", new EncryptorInfo("rc4", 16, 16, 1) }
  50. };
  51. }
  52. class Context
  53. {
  54. public int index1 = 0;
  55. public int index2 = 0;
  56. }
  57. private Context enc_ctx = new Context();
  58. private Context dec_ctx = new Context();
  59. private byte[] EncryptInitalize(byte[] key)
  60. {
  61. byte[] s = new byte[256];
  62. for (int i = 0; i < 256; i++)
  63. {
  64. s[i] = (byte)i;
  65. }
  66. for (int i = 0, j = 0; i < 256; i++)
  67. {
  68. j = (j + key[i % key.Length] + s[i]) & 255;
  69. Swap(s, i, j);
  70. }
  71. return s;
  72. }
  73. private void EncryptOutput(Context ctx, byte[] s, byte[] data, int length)
  74. {
  75. for (int n = 0; n < length; n++)
  76. {
  77. byte b = data[n];
  78. ctx.index1 = (ctx.index1 + 1) & 255;
  79. ctx.index2 = (ctx.index2 + s[ctx.index1]) & 255;
  80. Swap(s, ctx.index1, ctx.index2);
  81. data[n] = (byte)(b ^ s[(s[ctx.index1] + s[ctx.index2]) & 255]);
  82. }
  83. }
  84. private static void Swap(byte[] s, int i, int j)
  85. {
  86. byte c = s[i];
  87. s[i] = s[j];
  88. s[j] = c;
  89. }
  90. }
  91. }