PasswordDeriveBytesTest.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. //
  2. // PasswordDeriveTest.cs - NUnit Test Cases for PasswordDerive
  3. //
  4. // Author:
  5. // Sebastien Pouliot ([email protected])
  6. //
  7. // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
  8. //
  9. using NUnit.Framework;
  10. using System;
  11. using System.Security.Cryptography;
  12. namespace MonoTests.System.Security.Cryptography
  13. {
  14. // References:
  15. // a. PKCS#5: Password-Based Cryptography Standard
  16. // http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html
  17. public class PasswordDeriveBytesTest : TestCase
  18. {
  19. protected override void SetUp () {}
  20. protected override void TearDown () {}
  21. public void AssertEquals (string msg, byte[] array1, byte[] array2)
  22. {
  23. AllTests.AssertEquals (msg, array1, array2);
  24. }
  25. // generate the key up to HashSize and reset between operations
  26. public void ShortRun(string msg, PasswordDeriveBytes pd, byte[] finalKey)
  27. {
  28. for (int i=0; i < finalKey.Length; i++) {
  29. int j = 0;
  30. bool compare = true;
  31. byte[] key = pd.GetBytes (i+1);
  32. for (; j < i; j++) {
  33. if (finalKey [j] != key[j]) {
  34. compare = false;
  35. break;
  36. }
  37. }
  38. Assert (msg + " #" + j, compare);
  39. pd.Reset ();
  40. }
  41. }
  42. // generate a key at least 1000 bytes and don't reset between operations
  43. public void LongRun(string msg, PasswordDeriveBytes pd, byte[] finalKey)
  44. {
  45. int bloc = finalKey.Length;
  46. int iter = (int) ((1000 + bloc - 1) / bloc);
  47. byte[] pass = null;
  48. for (int i=0; i < iter; i++) {
  49. pass = pd.GetBytes (bloc);
  50. }
  51. AssertEquals (msg, pass, finalKey);
  52. }
  53. public void TestSHA1SaltShortRun ()
  54. {
  55. byte[] salt = { 0xDE, 0xAD, 0xC0, 0xDE };
  56. byte[] key = { 0x0B, 0x61, 0x93, 0x96, 0x3A, 0xFF, 0x0D, 0xFC, 0xF6, 0x3D, 0xA3, 0xDB, 0x34, 0xC2, 0x99, 0x71, 0x69, 0x11, 0x61, 0xB5 };
  57. PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", salt, "SHA1", 1);
  58. string msg = "PKCS#5 password salt SHA1 (1)";
  59. ShortRun (msg, pd, key);
  60. }
  61. public void TestSHA1SaltLongRun ()
  62. {
  63. byte[] salt = { 0xDE, 0xAD, 0xC0, 0xDE };
  64. byte[] key = { 0x91, 0xDA, 0xF9, 0x9D, 0x7C, 0xA9, 0xB4, 0x42, 0xB8, 0xD9, 0x45, 0xAB, 0x69, 0xEE, 0x12, 0xBC, 0x48, 0xDD, 0x38, 0x74 };
  65. PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", salt, "SHA1", 1);
  66. string msg = "PKCS#5-Long password salt SHA1 (1)";
  67. LongRun (msg, pd, key);
  68. }
  69. public void TestSHA1NoSaltShortRun ()
  70. {
  71. byte[] key = { 0x74, 0x61, 0x03, 0x6C, 0xA1, 0xFE, 0x85, 0x3E, 0xD9, 0x3F, 0x03, 0x06, 0x58, 0x45, 0xDE, 0x36, 0x52, 0xEF, 0x4B, 0x68 };
  72. PasswordDeriveBytes pd = new PasswordDeriveBytes ("mono", null, "SHA1", 10);
  73. string msg = "PKCS#5 mono null SHA1 (10)";
  74. ShortRun (msg, pd, key);
  75. }
  76. public void TestSHA1NoSaltLongRun ()
  77. {
  78. byte[] key = { 0x3A, 0xF8, 0x33, 0x88, 0x39, 0x61, 0x29, 0x75, 0x5C, 0x17, 0xD2, 0x9E, 0x8A, 0x78, 0xEB, 0xBD, 0x89, 0x1E, 0x4C, 0x67 };
  79. PasswordDeriveBytes pd = new PasswordDeriveBytes ("mono", null, "SHA1", 10);
  80. string msg = "PKCS#5-Long mono null SHA1 (10)";
  81. LongRun (msg, pd, key);
  82. }
  83. public void TestMD5SaltShortRun ()
  84. {
  85. byte[] salt = { 0xDE, 0xAD, 0xC0, 0xDE };
  86. byte[] key = { 0xA5, 0x4D, 0x4E, 0xDD, 0x3A, 0x59, 0xAC, 0x98, 0x08, 0xDA, 0xE7, 0xF2, 0x85, 0x2F, 0x7F, 0xF2 };
  87. PasswordDeriveBytes pd = new PasswordDeriveBytes ("mono", salt, "MD5", 100);
  88. string msg = "PKCS#5 mono salt MD5 (100)";
  89. ShortRun (msg, pd, key);
  90. }
  91. public void TestMD5SaltLongRun ()
  92. {
  93. byte[] salt = { 0xDE, 0xAD, 0xC0, 0xDE };
  94. byte[] key = { 0x92, 0x51, 0x4D, 0x10, 0xE1, 0x5F, 0xA8, 0x44, 0xEF, 0xFC, 0x0F, 0x1F, 0x6F, 0x3E, 0x40, 0x36 };
  95. PasswordDeriveBytes pd = new PasswordDeriveBytes ("mono", salt, "MD5", 100);
  96. string msg = "PKCS#5-Long mono salt MD5 (100)";
  97. LongRun (msg, pd, key);
  98. }
  99. public void TestMD5NoSaltShortRun ()
  100. {
  101. byte[] key = { 0x39, 0xEB, 0x82, 0x84, 0xCF, 0x1A, 0x3B, 0x3C, 0xA1, 0xF2, 0x68, 0xAF, 0xBF, 0xAC, 0x41, 0xA6 };
  102. PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", null, "MD5", 1000);
  103. string msg = "PKCS#5 password null MD5 (1000)";
  104. ShortRun (msg, pd, key);
  105. }
  106. public void TestMD5NoSaltLongRun ()
  107. {
  108. byte[] key = { 0x49, 0x3C, 0x00, 0x69, 0xB4, 0x55, 0x21, 0xA4, 0xC9, 0x69, 0x2E, 0xFF, 0xAA, 0xED, 0x4C, 0x72 };
  109. PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", null, "MD5", 1000);
  110. string msg = "PKCS#5-Long password null MD5 (1000)";
  111. LongRun (msg, pd, key);
  112. }
  113. public void TestProperties ()
  114. {
  115. byte[] salt = { 0xDE, 0xAD, 0xC0, 0xDE };
  116. // create object...
  117. PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", null, "MD5", 1000);
  118. // ...then change all its properties...
  119. pd.HashName = "SHA1";
  120. pd.Salt = salt;
  121. pd.IterationCount = 1;
  122. byte[] expectedKey = { 0x0b, 0x61, 0x93, 0x96 };
  123. // ... before using it
  124. AssertEquals ("PKCS#5 test properties", expectedKey, pd.GetBytes (4));
  125. // it should work but if we try to set any properties after GetBytes
  126. // they should all throw an exception
  127. try {
  128. pd.HashName = "SHA256";
  129. Fail ("PKCS#5 can't set HashName after GetBytes - expected CryptographicException but got none");
  130. }
  131. catch (CryptographicException) {
  132. // do nothing, this is what we expect
  133. }
  134. catch (Exception e) {
  135. Fail ("PKCS#5 can't set HashName after GetBytes - expected CryptographicException but got " + e.ToString ());
  136. }
  137. try {
  138. pd.Salt = expectedKey;
  139. Fail ("PKCS#5 can't set Salt after GetBytes - expected CryptographicException but got none");
  140. }
  141. catch (CryptographicException) {
  142. // do nothing, this is what we expect
  143. }
  144. catch (Exception e) {
  145. Fail ("PKCS#5 can't set Salt after GetBytes - expected CryptographicException but got " + e.ToString ());
  146. }
  147. try {
  148. pd.IterationCount = 10;
  149. Fail ("PKCS#5 can't set IterationCount after GetBytes - expected CryptographicException but got none");
  150. }
  151. catch (CryptographicException) {
  152. // do nothing, this is what we expect
  153. }
  154. catch (Exception e) {
  155. Fail ("PKCS#5 can't set IterationCount after GetBytes - expected CryptographicException but got " + e.ToString ());
  156. }
  157. // same thing after Reset
  158. pd.Reset ();
  159. try {
  160. pd.HashName = "SHA256";
  161. Fail ("PKCS#5 can't set HashName after Reset - expected CryptographicException but got none");
  162. }
  163. catch (CryptographicException) {
  164. // do nothing, this is what we expect
  165. }
  166. catch (Exception e) {
  167. Fail ("PKCS#5 can't set HashName after Reset - expected CryptographicException but got " + e.ToString ());
  168. }
  169. try {
  170. pd.Salt = expectedKey;
  171. Fail ("PKCS#5 can't set Salt after Reset - expected CryptographicException but got none");
  172. }
  173. catch (CryptographicException) {
  174. // do nothing, this is what we expect
  175. }
  176. catch (Exception e) {
  177. Fail ("PKCS#5 can't set Salt after Reset - expected CryptographicException but got " + e.ToString ());
  178. }
  179. try {
  180. pd.IterationCount = 10;
  181. Fail ("PKCS#5 can't set IterationCount after Reset - expected CryptographicException but got none");
  182. }
  183. catch (CryptographicException) {
  184. // do nothing, this is what we expect
  185. }
  186. catch (Exception e) {
  187. Fail ("PKCS#5 can't set IterationCount after Reset - expected CryptographicException but got " + e.ToString ());
  188. }
  189. }
  190. // FIXME: should we treat this as a bug or as a feature ?
  191. public void TestStrangeBehaviour ()
  192. {
  193. byte[] salt = { 0xDE, 0xAD, 0xC0, 0xDE };
  194. // create object with a salt...
  195. PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", salt, "MD5", 1000);
  196. // ...then change the salt to null
  197. try {
  198. pd.Salt = null;
  199. Fail ("PKCS#5 can't set Salt to null - expected NullReferenceException but got none");
  200. }
  201. catch (NullReferenceException) {
  202. // do nothing, this is what we (almost) expect
  203. }
  204. catch (Exception e) {
  205. Fail ("PKCS#5 can't set Salt to null - expected NullReferenceException but got " + e.ToString ());
  206. }
  207. }
  208. }
  209. }