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.

CryptographyTest.cs 5.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using Shadowsocks.Encryption;
  3. using Shadowsocks.Encryption.Stream;
  4. using Shadowsocks.Encryption.AEAD;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Threading;
  8. namespace Shadowsocks.Test
  9. {
  10. [TestClass]
  11. public class CryptographyTest
  12. {
  13. readonly Random random = new Random();
  14. [TestMethod]
  15. public void TestMD5()
  16. {
  17. for (int len = 1; len < 64; len++)
  18. {
  19. System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
  20. byte[] bytes = new byte[len];
  21. random.NextBytes(bytes);
  22. string md5str = Convert.ToBase64String(md5.ComputeHash(bytes));
  23. string md5str2 = Convert.ToBase64String(CryptoUtils.MD5(bytes));
  24. Assert.IsTrue(md5str == md5str2);
  25. }
  26. }
  27. #region Encryptor test tools
  28. private void SingleEncryptionTestCase(IEncryptor encryptor, IEncryptor decryptor, int length)
  29. {
  30. RNG.Reload();
  31. byte[] plain = new byte[length];
  32. byte[] cipher = new byte[plain.Length + 100];// AEAD with IPv4 address type needs +100
  33. byte[] plain2 = new byte[plain.Length + 16];
  34. random.NextBytes(plain);
  35. int outLen = encryptor.Encrypt(plain, cipher);
  36. int outLen2 = decryptor.Decrypt(plain2, cipher.AsSpan(0, outLen));
  37. //encryptor.Encrypt(plain, length, cipher, out int outLen);
  38. //decryptor.Decrypt(cipher, outLen, plain2, out int outLen2);
  39. Assert.AreEqual(length, outLen2);
  40. TestUtils.ArrayEqual<byte>(plain.AsSpan(0, length).ToArray(), plain2.AsSpan(0, length).ToArray());
  41. }
  42. const string password = "barfoo!";
  43. private void RunSingleEncryptionThread(Type enc, Type dec, string method)
  44. {
  45. var ector = enc.GetConstructor(new Type[] { typeof(string), typeof(string) });
  46. var dctor = dec.GetConstructor(new Type[] { typeof(string), typeof(string) });
  47. try
  48. {
  49. IEncryptor encryptor = (IEncryptor)ector.Invoke(new object[] { method, password });
  50. IEncryptor decryptor = (IEncryptor)dctor.Invoke(new object[] { method, password });
  51. for (int i = 0; i < 16; i++)
  52. {
  53. RunEncryptionRound(encryptor, decryptor);
  54. }
  55. }
  56. catch
  57. {
  58. encryptionFailed = true;
  59. throw;
  60. }
  61. }
  62. private static bool encryptionFailed = false;
  63. private void TestEncryptionMethod(Type enc, string method)
  64. {
  65. TestEncryptionMethod(enc, enc, method);
  66. }
  67. private void TestEncryptionMethod(Type enc, Type dec, string method)
  68. {
  69. encryptionFailed = false;
  70. // run it once before the multi-threading test to initialize global tables
  71. RunSingleEncryptionThread(enc, dec, method);
  72. List<Thread> threads = new List<Thread>();
  73. for (int i = 0; i < 8; i++)
  74. {
  75. Thread t = new Thread(new ThreadStart(() => RunSingleEncryptionThread(enc, dec, method))); threads.Add(t);
  76. t.Start();
  77. }
  78. foreach (Thread t in threads)
  79. {
  80. t.Join();
  81. }
  82. Assert.IsFalse(encryptionFailed);
  83. }
  84. #endregion
  85. // encryption test cases
  86. private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor)
  87. {
  88. SingleEncryptionTestCase(encryptor, decryptor, 7); // for not aligned data
  89. SingleEncryptionTestCase(encryptor, decryptor, 1000);
  90. SingleEncryptionTestCase(encryptor, decryptor, 12333);
  91. SingleEncryptionTestCase(encryptor, decryptor, 16384);
  92. }
  93. [TestMethod]
  94. public void TestAEADAesGcmNativeEncryption()
  95. {
  96. TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-128-gcm");
  97. TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-192-gcm");
  98. TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-256-gcm");
  99. }
  100. [TestMethod]
  101. public void TestAEADNaClEncryption()
  102. {
  103. TestEncryptionMethod(typeof(AEADNaClEncryptor), "chacha20-ietf-poly1305");
  104. TestEncryptionMethod(typeof(AEADNaClEncryptor), "xchacha20-ietf-poly1305");
  105. }
  106. [TestMethod]
  107. public void TestStreamNativeEncryption()
  108. {
  109. TestEncryptionMethod(typeof(StreamPlainNativeEncryptor), "plain");
  110. TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4");
  111. TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4-md5");
  112. }
  113. [TestMethod]
  114. public void TestStreamAesCfbBouncyCastleEncryption()
  115. {
  116. TestEncryptionMethod(typeof(StreamAesCfbBouncyCastleEncryptor), "aes-128-cfb");
  117. TestEncryptionMethod(typeof(StreamAesCfbBouncyCastleEncryptor), "aes-192-cfb");
  118. TestEncryptionMethod(typeof(StreamAesCfbBouncyCastleEncryptor), "aes-256-cfb");
  119. }
  120. [TestMethod]
  121. public void TestStreamChachaNaClEncryption()
  122. {
  123. TestEncryptionMethod(typeof(StreamChachaNaClEncryptor), "chacha20-ietf");
  124. }
  125. }
  126. }