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

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