DsaKeyTest.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using System;
  2. using System.IO;
  3. using System.Security.Cryptography;
  4. using System.Text;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. #if !NET6_0_OR_GREATER
  7. using Renci.SshNet.Common;
  8. #endif
  9. using Renci.SshNet.Security;
  10. using Renci.SshNet.Tests.Common;
  11. namespace Renci.SshNet.Tests.Classes.Security.Cryptography
  12. {
  13. [TestClass]
  14. public class DsaKeyTest : TestBase
  15. {
  16. private static DsaKey GetDsaKey(string fileName, string passPhrase = null)
  17. {
  18. using (var stream = GetData(fileName))
  19. {
  20. return (DsaKey)new PrivateKeyFile(stream, passPhrase).Key;
  21. }
  22. }
  23. // This is just to line up any differences in the assertion message.
  24. private static void AssertEqual(byte[] actualBytes, string expectedHex)
  25. {
  26. #if NET
  27. string actualHex = Convert.ToHexString(actualBytes);
  28. #else
  29. string actualHex = BitConverter.ToString(actualBytes).Replace("-", "");
  30. #endif
  31. Assert.AreEqual(expectedHex, actualHex,
  32. $"{Environment.NewLine}Expected: {expectedHex}{Environment.NewLine} Actual: {actualHex}");
  33. }
  34. // These tests generated by converting the keys to PKCS8, importing them to BCL DSA,
  35. // and printing out the expected DSAParameter values.
  36. // Some useful commands:
  37. // Generate a new params file with specific parameters:
  38. // openssl genpkey -genparam -algorithm dsa -pkeyopt pbits:1024 -pkeyopt qbits:160 -out dsa.1024.params
  39. // Generate PKCS8 key file from the params:
  40. // openssl genpkey -paramfile dsa.1024.params -out dsa.1024.txt
  41. // Convert to PKCS1:
  42. // openssl pkcs8 -in dsa.1024.txt -nocrypt -traditional -out dsa.1024.pkcs1.txt
  43. // Convert PKCS1 to ssh.com:
  44. // puttygen dsa.1024.pkcs1.txt -O private-sshcom -o dsa.1024.ssh2.txt
  45. // Convert to PKCS8:
  46. // openssl pkcs8 -topk8 -nocrypt -in Key.DSA.txt -out Key.DSA.PKCS8.txt
  47. /*
  48. using IndentedTextWriter tw = new(Console.Out);
  49. foreach (string filePath in Directory.EnumerateFiles(dir, "*.DSA.*txt"))
  50. {
  51. string pkFile = Path.GetFileNameWithoutExtension(filePath);
  52. tw.WriteLine("[TestMethod]");
  53. tw.WriteLine($"public void {pkFile.Replace('.', '_')}()");
  54. tw.WriteLine("{");
  55. tw.Indent++;
  56. tw.WriteLine($"DsaKey dsaKey = GetDsaKey(\"{pkFile}.txt\");");
  57. tw.WriteLine();
  58. tw.WriteLine("DSAParameters p = dsaKey.GetDSAParameters();");
  59. tw.WriteLine();
  60. using DSA dsa = DSA.Create();
  61. dsa.ImportFromPem(File.ReadAllText(filePath));
  62. DSAParameters p = dsa.ExportParameters(true);
  63. WriteParamAssert(p.P);
  64. WriteParamAssert(p.G);
  65. WriteParamAssert(p.Y);
  66. WriteParamAssert(p.Q);
  67. WriteParamAssert(p.X);
  68. tw.Indent--;
  69. tw.WriteLine("}");
  70. tw.WriteLine();
  71. }
  72. void WriteParamAssert(byte[] bytes, [CallerArgumentExpression(nameof(bytes))] string name = null)
  73. {
  74. tw.WriteLine($"AssertEqual({name}, \"{Convert.ToHexString(bytes)}\");");
  75. }
  76. */
  77. [TestMethod]
  78. public void Key_DSA()
  79. {
  80. DsaKey dsaKey = GetDsaKey("Key.DSA.txt");
  81. Assert.AreEqual(1024, dsaKey.P.GetBitLength());
  82. Assert.AreEqual(160, dsaKey.Q.GetBitLength());
  83. DSAParameters p = dsaKey.GetDSAParameters();
  84. AssertEqual(p.P, "B565DDF69ED8EE2AC2C00AF794944A15F428C50D3FECA5FEE4F79461FD4FF669B671D296B4F19D35970A5D20F752847826849C30E12F19B8682BF5020E01FF2BDC338BB7E2A92668D2F2D8B880C62A9DA1B65C346EB53EAC2A779203929DFC2C1B27F2D99BD76C6EF4D6A5A547CE892101D5CC82AF8CC564CAE6D30B5DC89415");
  85. AssertEqual(p.G, "0E549E37E14011DC79FA940E6758D7C53AE5151F75BB9C968FD054098883F1EC651B7713BDAAD0CD4DB5A458BDDCF6AC79F81ECE95EE3133B72FC973EB3505180C7085952F947B6C7721E26B91D7D9907F5E3CFDB9CB9034278FDCFBC5D7BD06A3E330399DFC35DE8CB93EDC9DEDDDCAAB9B440CCF0A8957488709178D40373D");
  86. AssertEqual(p.Y, "9BC2066506AD4BB33A01F3484CD586E1323B6766914232DBF7F316248203EDCFD5438CDD4D9746DE4A64D068FD9F8C6B7A8A4AE4D99801D8FCAED15F3C18265E5B6C2EAB7E6C1717929C56FFFED60B6F563975B7B7DD3249387E716B967EBF5F57B99FE1097FEAEFD9220A5036F9CD61ECDACEDDDF2BC1178C8D5D01712E4311");
  87. AssertEqual(p.Q, "AEFA2364A9FFD838062362B1D20871665807C461");
  88. AssertEqual(p.X, "18463B393E02299EA1BF7AE04F3E1EC40D97275E");
  89. }
  90. [TestMethod]
  91. public void Key_SSH2_DSA_Encrypted_Des_CBC_12345()
  92. {
  93. DsaKey dsaKey = GetDsaKey("Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt", "12345");
  94. Assert.AreEqual(1024, dsaKey.P.GetBitLength());
  95. Assert.AreEqual(160, dsaKey.Q.GetBitLength());
  96. DSAParameters p = dsaKey.GetDSAParameters();
  97. AssertEqual(p.P, "8F20C8715C86456190F8B0921923143A8DEB0DA71564EA572F6C2E316CDFCA0458B329030F7E735DF67AB529B4084D43A2595005591A596FFF7579864B120F20A17BD598E487EC3A587A5F475C642C012B2B04CD094FC8C16A02D6DCF6EBFBA1458DCC17EF11BB55E9637F5667265DFEDDCA8DC40555DB04574F97534A0BB5BD");
  98. AssertEqual(p.G, "04B63D3DBA0C7F4DD97A6E8ED7EA65F5EE17205602317188F954D38D83693A20799116B88BBE261A4BAF26201E121B78E6BEFC5B5C01AA4756D6054AEFF749F4C29C7172EB8DA02172949432BAA524CD2B141DBD1631C9DC67FB4142DF8D267441D59A7DB30F27DB4A1CA60DD654F75A5D3B5CE2993CDCD601EB2C06E9414FBE");
  99. AssertEqual(p.Y, "17F837B9770A37DCB325F56F08BC0E1D63C435C2C85DC9C006273872FAA605F5D09CC03D4F83EE046CF8D83E6CC9A29B15ACAF7BBFD421C7261C5CCAFF887867806C1DF6760DCF348AC7AEB9BE44A3CF27895A9790F9FBCD57708B22D3F4D72A5B52B78CFACF95CF5C28AF98E82CA7034B85F4A10D1121564D1079DE92E2EE16");
  100. AssertEqual(p.Q, "D8D7E6D3B7BB3688D998A011380BD85D5910B279");
  101. AssertEqual(p.X, "23FA5A574AF1197B185B88008A7A7527899FD092");
  102. }
  103. [TestMethod]
  104. public void Key_SSH2_DSA()
  105. {
  106. DsaKey dsaKey = GetDsaKey("Key.SSH2.DSA.txt");
  107. Assert.AreEqual(1024, dsaKey.P.GetBitLength());
  108. Assert.AreEqual(160, dsaKey.Q.GetBitLength());
  109. DSAParameters p = dsaKey.GetDSAParameters();
  110. AssertEqual(p.P, "E0921AE3B1C58FC3401A301BB7E44B7D00266C0DE1F0CF5D3A324DA01AC70A4E5A71895C58603F8225F8648A9696B19D45A46A32A931CD5BD6185AC0F58DE2CC684FC4116FA4805B7D04AE74FFA54B6CC6AA059641656B8C6F59280D02E1C0564501AE03EC278B077A149B3459F723AABC46095EDA3C870C74CEA8F8F62845E1");
  111. AssertEqual(p.G, "2BBCFEC01A1E6363ECF179045BE76CF17146A644191560BFDF7AB749362F61A0CF1968EE3EF9782CF3031BA66A04721F43B1776DB9F8EA5D6A64EF2C253E371D861B1BDCCC4901E11E16D4D1B2EDBF2144CAA8A3C720E82888FCECF2AEBD0315A1575D1A0C351D6162E4A8F57FB4C1A5E92FE30BBBD324B9A166E9B8054BFC31");
  112. AssertEqual(p.Y, "B75F681CF20FCAFFFC99B31A629BBC23A92F8F5FFDEC48F0D2778DEC277D70664BA883C1C13C941C442F292026E01BCD3F42DEDC90E7DD115ACA14667FEF11AC0992E1DD4C8EB08EB3A7E67B22E7936913A513C5676C741F5B9D211021CD17A1C9F8FA3AC0079FB25C96BFA6A83868ABB9C87C2DED4A05B1147E60F78F3EEE4B");
  113. AssertEqual(p.Q, "BBE34624549755A532514F177D3328B4371DEDE3");
  114. AssertEqual(p.X, "66504B5D937CD2319275BA6527352A39CC2F94C4");
  115. }
  116. [TestMethod]
  117. public void Key_DSA_3072_256()
  118. {
  119. // Not supported by OpenSSH but easy enough to test here.
  120. var keyString = """
  121. -----BEGIN DSA PRIVATE KEY-----
  122. MIIE1gIBAAKCAYEA6Rb9Cogx64CZcrnP35Nr8W9sjcUqoCpSfZrJdvIhTxgyAkEl
  123. d9U868azCTZ1QGvUuPOCGB5Ll8nRQ6QSK9bicSQ3q3C69BcjzTfZcFuZEi533wEl
  124. 9m9xZTbMAW8643jgARKszoNWIeTGsk2JcXQ2c6+VfPOml6F7yMv3KDIpqjUQlpK+
  125. RoZn5Eg5R2+2VqcNwwqbP8dyQGnGmgX2hlzbWx9Cld8NTG2b0B6Taaea4zqiMLHC
  126. MeOUh+3WkbGM+aVQ7kthQbkhTEMmZeB/zyJrlEQGmKJl/cuvx69iO8nPSIZJDSEp
  127. sZwg6p+Fqlm0+IyaFaxJMF+SuQirYLR+ee5oor5lcWS3Szaaikz0u1ONO3ndWAmO
  128. eEHq7BL4vuHc/SDxfO5RouhEirCUFtGwtYq/Kf7x53ccd0Jmlj1FalubKHaiyYSg
  129. baHrvN8rFv12XDMI0vPDeOxLVaxaB3zSJTz/ZwDjUcFx7PbuWsvOoSZeagd0sCm9
  130. aVNQoe7dy/5YCrM7AiEA1oznSuokVWnPt9GaBlmggzk9lMjZ/XVr9MFuDzWDycsC
  131. ggGAYVSdm43WuonZQ40M9An5oBZuWsv22ZNXFnMXzcrKkvdslWGP+za/Ipa+tm+j
  132. YE82vuqCdGjDuDJViJbrx2FProe4J/to2Gpd0jc0uV2c1PFO0B1hDk7tkglQyhmV
  133. q9GAQatA4XUM5cIiInseF5JxHMmfgwEKmfIUDotWnpFQImMvehHxZfI29ngrB2ND
  134. Ba4wBIj1Ua4UqsQi2beNfope7+XSsBQm98prswjvdR6n6wg9Xkvtn4ti3lLbEHzO
  135. ZlwnxoRxFlNE/s2RaygGySRRYAe9TPriGWeMpWirYF3/SDAQyt5qDJsPQU0fWAuF
  136. WsuxDlOsaLmJNJNnvySwx5Qmiw4e17U+6/IKptVbOHWowq05PxZKSVYmcP5+Jbt2
  137. eVzozKPNGkEw6aBy18l4t+ehx7fiUha7uCPaZ+VTPodLRZE6sKT1uiKOBtPqhrsp
  138. bxKJ3zzmF1KZpoOG++1JHzqOPL+Npokd+K3ce9vNfU7eWTYP2DuiooyF9EktJt7w
  139. AVilAoIBgBCpFSwJxhdAIQRefnQmweW+eXRbx8KL+8t53YsPS/fQhdzIEVEi5LWz
  140. cJ0iAU2l2Mj43AC/6yehA8KF6vJEy4LWSXNwoGVqEoSA2LxBaomLxLARqlFyfCZN
  141. yBlUVfXDiqFw2ajRaLQKUIxWbfC6ard69brWZuS61YQd8Jrk782VAa+sQO6Ca6Ii
  142. vtyyRjNKxbeYwKLkZydi9JFdYYR6kmVG1ge7spemMHlozza6VvNcDU3hE4T4PwbY
  143. Ns555ihK79EWGO2zCNjhPEIN34IjN2WjbUidCBWPGgXLhw9BYyEEREhfP1QUTe2q
  144. S3gup/j8//v46O+OZFcB6g/MZB2IFpRRSw16qM2+pNZFKVTvXs/dUq5tEXylbMCg
  145. +7jS5eLVAkDYFwSUai4Ht9VOHGASz7VyfPfngL8nx+KLNyegB12OLwr6ho5tc9dE
  146. Rib63kEJnsK6CzIjg1+iFblWy4pQsHnKEgvBWxk4+sLyEZFTtjCe7KjigdH6WRDH
  147. U5ejA3bnFQIhAIkT3ff8AjkByyJg1CRkpwDCvFag1fbPXEdg1Ru1E+l/
  148. -----END DSA PRIVATE KEY-----
  149. """;
  150. using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(keyString));
  151. DsaKey dsaKey = (DsaKey)new PrivateKeyFile(stream).Key;
  152. Assert.AreEqual(3072, dsaKey.P.GetBitLength());
  153. Assert.AreEqual(256, dsaKey.Q.GetBitLength());
  154. DSAParameters p = dsaKey.GetDSAParameters();
  155. AssertEqual(p.P, "E916FD0A8831EB809972B9CFDF936BF16F6C8DC52AA02A527D9AC976F2214F183202412577D53CEBC6B3093675406BD4B8F382181E4B97C9D143A4122BD6E2712437AB70BAF41723CD37D9705B99122E77DF0125F66F716536CC016F3AE378E00112ACCE835621E4C6B24D8971743673AF957CF3A697A17BC8CBF7283229AA35109692BE468667E44839476FB656A70DC30A9B3FC7724069C69A05F6865CDB5B1F4295DF0D4C6D9BD01E9369A79AE33AA230B1C231E39487EDD691B18CF9A550EE4B6141B9214C432665E07FCF226B94440698A265FDCBAFC7AF623BC9CF4886490D2129B19C20EA9F85AA59B4F88C9A15AC49305F92B908AB60B47E79EE68A2BE657164B74B369A8A4CF4BB538D3B79DD58098E7841EAEC12F8BEE1DCFD20F17CEE51A2E8448AB09416D1B0B58ABF29FEF1E7771C774266963D456A5B9B2876A2C984A06DA1EBBCDF2B16FD765C3308D2F3C378EC4B55AC5A077CD2253CFF6700E351C171ECF6EE5ACBCEA1265E6A0774B029BD695350A1EEDDCBFE580AB33B");
  156. AssertEqual(p.G, "61549D9B8DD6BA89D9438D0CF409F9A0166E5ACBF6D99357167317CDCACA92F76C95618FFB36BF2296BEB66FA3604F36BEEA827468C3B832558896EBC7614FAE87B827FB68D86A5DD23734B95D9CD4F14ED01D610E4EED920950CA1995ABD18041AB40E1750CE5C222227B1E1792711CC99F83010A99F2140E8B569E915022632F7A11F165F236F6782B07634305AE300488F551AE14AAC422D9B78D7E8A5EEFE5D2B01426F7CA6BB308EF751EA7EB083D5E4BED9F8B62DE52DB107CCE665C27C68471165344FECD916B2806C924516007BD4CFAE219678CA568AB605DFF483010CADE6A0C9B0F414D1F580B855ACBB10E53AC68B989349367BF24B0C794268B0E1ED7B53EEBF20AA6D55B3875A8C2AD393F164A49562670FE7E25BB76795CE8CCA3CD1A4130E9A072D7C978B7E7A1C7B7E25216BBB823DA67E5533E874B45913AB0A4F5BA228E06D3EA86BB296F1289DF3CE6175299A68386FBED491F3A8E3CBF8DA6891DF8ADDC7BDBCD7D4EDE59360FD83BA2A28C85F4492D26DEF00158A5");
  157. AssertEqual(p.Y, "10A9152C09C6174021045E7E7426C1E5BE79745BC7C28BFBCB79DD8B0F4BF7D085DCC8115122E4B5B3709D22014DA5D8C8F8DC00BFEB27A103C285EAF244CB82D6497370A0656A128480D8BC416A898BC4B011AA51727C264DC8195455F5C38AA170D9A8D168B40A508C566DF0BA6AB77AF5BAD666E4BAD5841DF09AE4EFCD9501AFAC40EE826BA222BEDCB246334AC5B798C0A2E4672762F4915D61847A926546D607BBB297A6307968CF36BA56F35C0D4DE11384F83F06D836CE79E6284AEFD11618EDB308D8E13C420DDF82233765A36D489D08158F1A05CB870F4163210444485F3F54144DEDAA4B782EA7F8FCFFFBF8E8EF8E645701EA0FCC641D881694514B0D7AA8CDBEA4D6452954EF5ECFDD52AE6D117CA56CC0A0FBB8D2E5E2D50240D81704946A2E07B7D54E1C6012CFB5727CF7E780BF27C7E28B3727A0075D8E2F0AFA868E6D73D7444626FADE41099EC2BA0B3223835FA215B956CB8A50B079CA120BC15B1938FAC2F2119153B6309EECA8E281D1FA5910C75397A30376E715");
  158. AssertEqual(p.Q, "D68CE74AEA245569CFB7D19A0659A083393D94C8D9FD756BF4C16E0F3583C9CB");
  159. AssertEqual(p.X, "8913DDF7FC023901CB2260D42464A700C2BC56A0D5F6CF5C4760D51BB513E97F");
  160. }
  161. }
  162. }