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.

CryptoFactory.cs 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using System.Text;
  5. using Shadowsocks.Common.Crypto;
  6. using Shadowsocks.Common.Model;
  7. using Shadowsocks.Crypto.AEAD;
  8. using Shadowsocks.Crypto.Stream;
  9. namespace Shadowsocks.Crypto
  10. {
  11. public static class CryptoFactory
  12. {
  13. public static string DefaultCipher = "chacha20-ietf-poly1305";
  14. private static readonly Dictionary<string, Type> _registeredEncryptors = new Dictionary<string, Type>();
  15. private static readonly Dictionary<string, CipherInfo> ciphers = new Dictionary<string, CipherInfo>();
  16. private static readonly Type[] ConstructorTypes = { typeof(string), typeof(string) };
  17. static CryptoFactory()
  18. {
  19. foreach (var method in StreamPlainNativeCrypto.SupportedCiphers())
  20. {
  21. if (!_registeredEncryptors.ContainsKey(method.Key))
  22. {
  23. ciphers.Add(method.Key, method.Value);
  24. _registeredEncryptors.Add(method.Key, typeof(StreamPlainNativeCrypto));
  25. }
  26. }
  27. foreach (var method in StreamRc4NativeCrypto.SupportedCiphers())
  28. {
  29. if (!_registeredEncryptors.ContainsKey(method.Key))
  30. {
  31. ciphers.Add(method.Key, method.Value);
  32. _registeredEncryptors.Add(method.Key, typeof(StreamRc4NativeCrypto));
  33. }
  34. }
  35. foreach (var method in StreamAesCfbBouncyCastleCrypto.SupportedCiphers())
  36. {
  37. if (!_registeredEncryptors.ContainsKey(method.Key))
  38. {
  39. ciphers.Add(method.Key, method.Value);
  40. _registeredEncryptors.Add(method.Key, typeof(StreamAesCfbBouncyCastleCrypto));
  41. }
  42. }
  43. foreach (var method in StreamChachaNaClCrypto.SupportedCiphers())
  44. {
  45. if (!_registeredEncryptors.ContainsKey(method.Key))
  46. {
  47. ciphers.Add(method.Key, method.Value);
  48. _registeredEncryptors.Add(method.Key, typeof(StreamChachaNaClCrypto));
  49. }
  50. }
  51. foreach (var method in AEADAesGcmNativeCrypto.SupportedCiphers())
  52. {
  53. if (!_registeredEncryptors.ContainsKey(method.Key))
  54. {
  55. ciphers.Add(method.Key, method.Value);
  56. _registeredEncryptors.Add(method.Key, typeof(AEADAesGcmNativeCrypto));
  57. }
  58. }
  59. foreach (var method in AEADNaClCrypto.SupportedCiphers())
  60. {
  61. if (!_registeredEncryptors.ContainsKey(method.Key))
  62. {
  63. ciphers.Add(method.Key, method.Value);
  64. _registeredEncryptors.Add(method.Key, typeof(AEADNaClCrypto));
  65. }
  66. }
  67. }
  68. public static ICrypto GetEncryptor(string method, string password)
  69. {
  70. if (string.IsNullOrEmpty(method))
  71. {
  72. // todo
  73. //method = IoCManager.Container.Resolve<IDefaultCrypto>().GetDefaultMethod();
  74. }
  75. method = method.ToLowerInvariant();
  76. bool ok = _registeredEncryptors.TryGetValue(method, out Type t);
  77. if (!ok)
  78. {
  79. t = _registeredEncryptors[DefaultCipher];
  80. }
  81. ConstructorInfo c = t?.GetConstructor(ConstructorTypes) ??
  82. throw new TypeLoadException("can't load constructor");
  83. if (c == null) throw new System.Exception("Invalid ctor");
  84. ICrypto result = (ICrypto)c.Invoke(new object[] { method, password });
  85. return result;
  86. }
  87. public static string DumpRegisteredEncryptor()
  88. {
  89. var sb = new StringBuilder();
  90. sb.Append(Environment.NewLine);
  91. sb.AppendLine("-------------------------");
  92. sb.AppendLine("Registered Encryptor Info");
  93. foreach (var encryptor in _registeredEncryptors)
  94. {
  95. sb.AppendLine($"{ciphers[encryptor.Key].ToString(true)} => {encryptor.Value.Name}");
  96. }
  97. // use ----- instead of =======, so when user paste it to Github, it won't became title
  98. sb.AppendLine("-------------------------");
  99. return sb.ToString();
  100. }
  101. public static CipherInfo GetCipherInfo(string name)
  102. {
  103. // TODO: Replace cipher when required not exist
  104. return ciphers[name];
  105. }
  106. public static IEnumerable<CipherInfo> ListAvaliableCiphers()
  107. {
  108. return ciphers.Values;
  109. }
  110. }
  111. }