mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-10-26 11:09:32 +08:00
@@ -16,6 +16,7 @@
|
||||
New Features:
|
||||
|
||||
* Improved accuracy of IsConnected on .NET
|
||||
* Added support for ssh.com (SSH-2) private keys (issue #1987)
|
||||
|
||||
Fixes:
|
||||
|
||||
|
||||
@@ -775,10 +775,24 @@
|
||||
<Link>Renci.SshNet.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt">
|
||||
<Link>Data\Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt</Link>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.SSH2.DSA.txt">
|
||||
<Link>Data\Key.SSH2.DSA.txt</Link>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt">
|
||||
<Link>Data\Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt</Link>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.SSH2.RSA.txt">
|
||||
<Link>Data\Key.SSH2.RSA.txt</Link>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
|
||||
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
@@ -146,6 +146,113 @@ namespace Renci.SshNet.Tests.Classes
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_DSA()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.DSA.txt"))
|
||||
{
|
||||
new PrivateKeyFile(stream);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_RSA()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.RSA.txt"))
|
||||
{
|
||||
new PrivateKeyFile(stream);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_Encrypted_DSA_DES_CBC()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt"))
|
||||
{
|
||||
new PrivateKeyFile(stream, "12345");
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_Encrypted_RSA_DES_CBC()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt"))
|
||||
{
|
||||
new PrivateKeyFile(stream, "12345");
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_Encrypted_ShouldThrowSshExceptionWhenPassphraseIsWrong()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt"))
|
||||
{
|
||||
try
|
||||
{
|
||||
new PrivateKeyFile(stream, "34567");
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (SshException ex)
|
||||
{
|
||||
Assert.IsInstanceOfType(ex, typeof(SshException));
|
||||
Assert.IsNull(ex.InnerException);
|
||||
Assert.AreEqual("Invalid passphrase.", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_Encrypted_ShouldThrowSshPassPhraseNullOrEmptyExceptionWhenPassphraseIsNull()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt"))
|
||||
{
|
||||
try
|
||||
{
|
||||
new PrivateKeyFile(stream, null);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (SshPassPhraseNullOrEmptyException ex)
|
||||
{
|
||||
Assert.IsInstanceOfType(ex, typeof(SshPassPhraseNullOrEmptyException));
|
||||
Assert.IsNull(ex.InnerException);
|
||||
Assert.AreEqual("Private key is encrypted but passphrase is empty.", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("drieseng")]
|
||||
[TestCategory("PrivateKey")]
|
||||
public void Test_PrivateKey_SSH2_Encrypted_ShouldThrowSshPassPhraseNullOrEmptyExceptionWhenPassphraseIsEmpty()
|
||||
{
|
||||
using (var stream = this.GetData("Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt"))
|
||||
{
|
||||
try
|
||||
{
|
||||
new PrivateKeyFile(stream, string.Empty);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (SshPassPhraseNullOrEmptyException ex)
|
||||
{
|
||||
Assert.IsInstanceOfType(ex, typeof(SshPassPhraseNullOrEmptyException));
|
||||
Assert.IsNull(ex.InnerException);
|
||||
Assert.AreEqual("Private key is encrypted but passphrase is empty.", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Owner("olegkap")]
|
||||
[TestCategory("PrivateKey")]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
P2/56wAAAgoAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA
|
||||
AIM2Rlcy1jYmMAAAHIxrKV3QJkISlRHox4JYLlWJG0ccdEfMmDF3IXW+up6nUQZeWyOS9/
|
||||
csXyclUtJ/adA0qkpH5hcaIIOr1jQgvPxjMy7o3I5WJ/MvKB7omSDYG82wKZAaZQeSCaqY
|
||||
Cn1DYHz6Xou5BIle37f0y71tq3d7YFCh33BjbCM8KHsar3TgRf3oegaawZyZuLnnZRy0L+
|
||||
xdsdqgntc4fyhpmCmfwIYhWwD2R9P56FXTw59VuE0r/LxxLJW8Cq2R8i7bN0lb2ezb3qnU
|
||||
SykSJ5PYvoW6e7HIZ3GEr9d+wDhqp0SKWHl+shed3e5xi1NF7fRR23bZ1xlAk3FdrBrH1b
|
||||
aWYW4JFzdVc33Pg5oHLe+q5NQ3vQpMxXlN2IG9cdAigWKNJMdvLuxiYi+6lzNIGAH+yb01
|
||||
56ksXYgUs65Gqnj0GMYVmf//8NN0gRKXl5dT57LyuU42jRePwANMyO/n9QOi9OKeea8Tku
|
||||
f6ZMRiHQLDiZx2ShEXEhHRwmv42jt2xjuHNMbY0dZTKZEkFMUGVFVbkl5MEmN8Fj59rHJn
|
||||
0adWRPLH5smwM8WXbaYt+E0r628UNZbedXCcjZ5c5egpxCBxRrSJqnK1f0l899fulB
|
||||
---- END SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
@@ -0,0 +1,12 @@
|
||||
---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA
|
||||
AEbm9uZQAAAcQAAAHAAAAAAAAABACPIMhxXIZFYZD4sJIZIxQ6jesNpxVk6lcvbC4xbN/K
|
||||
BFizKQMPfnNd9nq1KbQITUOiWVAFWRpZb/91eYZLEg8goXvVmOSH7DpYel9HXGQsASsrBM
|
||||
0JT8jBagLW3Pbr+6FFjcwX7xG7Veljf1ZnJl3+3cqNxAVV2wRXT5dTSgu1vQAAA/sEtj09
|
||||
ugx/Tdl6bo7X6mX17hcgVgIxcYj5VNONg2k6IHmRFriLviYaS68mIB4SG3jmvvxbXAGqR1
|
||||
bWBUrv90n0wpxxcuuNoCFylJQyuqUkzSsUHb0WMcncZ/tBQt+NJnRB1Zp9sw8n20ocpg3W
|
||||
VPdaXTtc4pk83NYB6ywG6UFPvgAAAKDY1+bTt7s2iNmYoBE4C9hdWRCyeQAAA/0X+De5dw
|
||||
o33LMl9W8IvA4dY8Q1wshdycAGJzhy+qYF9dCcwD1Pg+4EbPjYPmzJopsVrK97v9QhxyYc
|
||||
XMr/iHhngGwd9nYNzzSKx665vkSjzyeJWpeQ+fvNV3CLItP01ypbUreM+s+Vz1wor5joLK
|
||||
cDS4X0oQ0RIVZNEHnekuLuFgAAAJ4j+lpXSvEZexhbiACKenUniZ/Qkg==
|
||||
---- END SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
@@ -0,0 +1,23 @@
|
||||
---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
Comment: "imported-openssh-key"
|
||||
P2/56wAAA/MAAAA3aWYtbW9kbntzaWdue3JzYS1wa2NzMS1zaGExfSxlbmNyeXB0e3JzYS
|
||||
1wa2NzMXYyLW9hZXB9fQAAAAgzZGVzLWNiYwAAA6A6Wt6IR5cz0PCsSJDOjcs3MdQscfdN
|
||||
p54qdp1DPUltmJJCwxU31izkP+mdRoSBgTwAd2jIvq+xdxhe8ZYqFtf6QvbIsZMWC/giRU
|
||||
mDcHLnGxWgWDY9adh5AscC7FOTEXhME/uNkGdYp3x5lmmC8uHC6cKt4RIqq7elBnOlnNvQ
|
||||
Mmr0mJluLsqsu4pr57bM0TJ37s7ov33zLuINO40kZ1Yc9A0NebWoGZPB8Wq2UCVskAXM6v
|
||||
/cJQRNu73Hn77vbLhzVEKnOokRdzDncKRMkItwJV0iz4/kuAcf6OdgwmPQ2e/lz7NR+5yI
|
||||
a37bKeKKnOR4JGAIjSoGu/Skc8GKfcEPAnnZ2xYJ15fNPy5fBbga8SAQGJ3UCx1cPsaaTA
|
||||
pt0fJ5si9X26V8XrK+T0mRBZPjj0s/eb2jOAzgWPCur4N3hqijyQO7RoTjh1jcL7ONT9zv
|
||||
HJjqqaTXMqQGPeHEpSamyTyXMDwMZGRAaGQDM1awWX3jq1uNgGW/3/0TV/rq69nVso3dVv
|
||||
DiSPGdK+GgZzVWsfZv/5X17YrQLEkr0s6Mpsm5L3j4NYtcppMR2bV3vsA9eCWb99lnvhIt
|
||||
bR12MY21S/o1CwAtSYZojylcxZcWVaoZ20OTzrzTjsCOLxyIiQAzdKFG49F+YCUIJYM8ne
|
||||
NA+jW34x7u1L+NKVHMPUx7gcYEE6RapEOQRx1p+9HV7efGNIOmpUCZJZ4itHFUSOxi6eao
|
||||
FT8J2si0edrDMnWDdRBhOMQNkSt9zViWpIvLLx4g9jih6XEgAOsRTyD9GnpM6HBspd+Jsy
|
||||
XfSgbfBsJpnHOpjx/mTiQ0AkfkBeOvgfGRWyjjSfJaxojnE59JHo1HR6+9XFuWGXjYbIYo
|
||||
gpcLnJ1JY/to21ABQgsNCxH1VocPNGTKodcDpf91bYKqS4peri9CKSXsRP3Y4K7cffwXAH
|
||||
kWFvvfw65pZHx9xTJfgv986jfn1JCDrO/6UOwnyrL2X8g9wrCEQ1R0QNQ82mx+cXu4atVO
|
||||
oA2Hjj5OegwHScGTZ9LaC+CRyW847QrJF7sPDcYxbEUTvgSSGZ+dymAjFFNMlBdMAEmtNB
|
||||
P0dBUFObJsP0vTyZrxnueal6zleQY1ox5csO3XF2nKpO+KjfuVd6qM6/7sBpqpA1bycM2O
|
||||
8k6Wq2hSEhPVovarOb878P1Uiuzr4eb/eIt7tC1SHrcfAoBIYnUYVzUB5g4WIIy3qxEaGm
|
||||
36ETbq3U+vVk9BatC4
|
||||
---- END SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
@@ -0,0 +1,23 @@
|
||||
---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
Comment: "imported-openssh-key"
|
||||
P2/56wAAA+4AAAA3aWYtbW9kbntzaWdue3JzYS1wa2NzMS1zaGExfSxlbmNyeXB0e3JzYS
|
||||
1wa2NzMXYyLW9hZXB9fQAAAARub25lAAADnwAAA5sAAAARAQABAAAIAJoF62h2fdR02ncN
|
||||
StzmpuKmvnAdQdbkAlzek1LBuXrJX2wsF6XcqsLSAvAHhvy71q6TK9GBQOgpGH3vn+Tjo2
|
||||
POKZL/2u9sN52yanbQw0oFCDOHBy2xCRw/+NoOofcVtR59eeSKMy79gmkGQnsCliqdznXX
|
||||
GUuZSxHIQQZhfcCbYuGHCjA6B8dsFeVzrzwju1lr3eEtuChCpgnWHevbyasOYWTj3/Mt/W
|
||||
x0XEAQQB9jutL4VpzNzsE1D47dLfVWAflYppCcxFH8LS7Sq5NEUFs0Vje1LJK6XhrfieH8
|
||||
YjQfpsikbpcTIebIHP74W3RjBhcKt7eBoHhcSj8vU5pPj3EAAAgA1cGcbXOCOZ54AvKgLu
|
||||
7ibJfchKnHAOTG1BxMkxy/0pCoTPSDAXiHyNxjN4qjk8nqg1dfsPdjXCRpW+eBsQMhJZ1P
|
||||
qIh4WB7fkK7+Wm4twhqQhLQ7uPwjnNflNYqRizeYJ5wUofuK2I30DgiNQjw2hV6Tos8ikv
|
||||
VA7GCedjnScRYbUauV8rrXC6+Xny6mD2F3BGE/CQdYTZXNs7mKIkCpb9ziJXMM7juCfBSO
|
||||
qQSwZy7XeEKuMqzP9diHCByqqCcippHc0RZTLONCTWa7ndoqAdhZpkk/pDqmFTEWEJuUPN
|
||||
8jWCqukS4RzxXEE3lbzZbInYmsldlXIeboQoFJM+4WXwAABAC84bFrW0L1E2GtgVp2uZoi
|
||||
Ve1ynoXmr7nHfCmbVJS5nEZBYTKT+62/VdlDiLm7QlnQqpkxyYw+d3pM3rvHLAb/6ntoIs
|
||||
l5HJG4WWDl0vQVwjQR5CQpRrtLQiDIhMAxBdKGS5Ql9RpdQKvhFI+7STzttqcDCerOEVQG
|
||||
SlT3vL52UAAABADgL9iwue1u7D6IrL26PwudbJSZ3lPt3YkZl25LDIVrGU5U0xPH3o+FQP
|
||||
GTkQv5qrc43I96Jc+P9d7A2EyE6j+ArtSWKq5OrVUAhg16O49rc2ve5v4w53fOH0P20BHv
|
||||
k1QxIEg5vHAJwgfZMJ68ub6+73gtkSHJ6W78T2Qpo+dHtwAABAD0Fti2uUlPoiDmhOIZUF
|
||||
7qs3pxkC+OjZcWBgi7IsEjiBxZVmYH3iD722gmbA4om6ulAxs7F2q10l0YXY1ds250FOxQ
|
||||
swT2var18A0MjOWa7RgHChBqiHxi+krLW6F9UvllWYmb4bz4E1T3rfE4OB0h5UW2oHD4Hn
|
||||
smPA/t9MmWmQ==
|
||||
---- END SSH2 ENCRYPTED PRIVATE KEY ----
|
||||
@@ -342,6 +342,16 @@
|
||||
<Link>Renci.SshNet.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Data\Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Data\Key.SSH2.RSA.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Data\Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt" />
|
||||
<EmbeddedResource Include="Data\Key.SSH2.DSA.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -16,17 +16,46 @@ using System.Diagnostics.CodeAnalysis;
|
||||
namespace Renci.SshNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents private key information
|
||||
/// Represents private key information.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code source="..\..\Renci.SshNet.Tests\Data\Key.RSA.txt" language="Text" title="Private RSA key example" />
|
||||
/// </example>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Supports RSA and DSA private key in both <c>OpenSSH</c> and <c>ssh.com</c> format.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The following encryption algorithms are supported:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description>DES-EDE3-CBC</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>DES-EDE3-CFB</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>DES-CBC</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>AES-128-CBC</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>AES-192-CBC</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>AES-256-CBC</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class PrivateKeyFile : IDisposable
|
||||
{
|
||||
private static readonly Regex PrivateKeyRegex = new Regex(@"^-+ *BEGIN (?<keyName>\w+( \w+)*) PRIVATE KEY *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)-+ *END \k<keyName> PRIVATE KEY *-+",
|
||||
#if SILVERLIGHT
|
||||
private static readonly Regex _privateKeyRegex = new Regex(@"^-+ *BEGIN (?<keyName>\w+( \w+)*) PRIVATE KEY *-+\r?\n(Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)-+ *END \k<keyName> PRIVATE KEY *-+", RegexOptions.Multiline);
|
||||
RegexOptions.Multiline);
|
||||
#else
|
||||
private static readonly Regex _privateKeyRegex = new Regex(@"^-+ *BEGIN (?<keyName>\w+( \w+)*) PRIVATE KEY *-+\r?\n(Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)-+ *END \k<keyName> PRIVATE KEY *-+", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
#endif
|
||||
|
||||
private Key _key;
|
||||
@@ -101,7 +130,7 @@ namespace Renci.SshNet
|
||||
using (var sr = new StreamReader(privateKey))
|
||||
{
|
||||
var text = sr.ReadToEnd();
|
||||
privateKeyMatch = _privateKeyRegex.Match(text);
|
||||
privateKeyMatch = PrivateKeyRegex.Match(text);
|
||||
}
|
||||
|
||||
if (!privateKeyMatch.Success)
|
||||
@@ -177,7 +206,7 @@ namespace Renci.SshNet
|
||||
throw new SshException("Invalid SSH2 private key.");
|
||||
}
|
||||
|
||||
var totalLength = reader.ReadUInt32(); // Read total bytes length including magic number
|
||||
reader.ReadUInt32(); // Read total bytes length including magic number
|
||||
var keyType = reader.ReadString();
|
||||
var ssh2CipherName = reader.ReadString();
|
||||
var blobSize = (int)reader.ReadUInt32();
|
||||
@@ -187,12 +216,15 @@ namespace Renci.SshNet
|
||||
{
|
||||
keyData = reader.ReadBytes(blobSize);
|
||||
}
|
||||
//else if (ssh2CipherName == "3des-cbc")
|
||||
//{
|
||||
// var key = GetCipherKey(passPhrase, 192 / 8);
|
||||
// var ssh2Сipher = new TripleDesCipher(key, null, null);
|
||||
// keyData = ssh2Сipher.Decrypt(reader.ReadBytes(blobSize));
|
||||
//}
|
||||
else if (ssh2CipherName == "3des-cbc")
|
||||
{
|
||||
if (string.IsNullOrEmpty(passPhrase))
|
||||
throw new SshPassPhraseNullOrEmptyException("Private key is encrypted but passphrase is empty.");
|
||||
|
||||
var key = GetCipherKey(passPhrase, 192 / 8);
|
||||
var ssh2Сipher = new TripleDesCipher(key, new CbcCipherMode(new byte[8]), new PKCS7Padding());
|
||||
keyData = ssh2Сipher.Decrypt(reader.ReadBytes(blobSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new SshException(string.Format("Cipher method '{0}' is not supported.", cipherName));
|
||||
@@ -204,7 +236,7 @@ namespace Renci.SshNet
|
||||
|
||||
var decryptedLength = reader.ReadUInt32();
|
||||
|
||||
if (decryptedLength + 4 != blobSize)
|
||||
if (decryptedLength > blobSize - 4)
|
||||
throw new SshException("Invalid passphrase.");
|
||||
|
||||
if (keyType == "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}")
|
||||
@@ -245,22 +277,19 @@ namespace Renci.SshNet
|
||||
|
||||
private static byte[] GetCipherKey(string passphrase, int length)
|
||||
{
|
||||
List<byte> cipherKey = new List<byte>();
|
||||
var cipherKey = new List<byte>();
|
||||
|
||||
using (var md5 = new MD5Hash())
|
||||
{
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes(passphrase);
|
||||
|
||||
var hash = md5.ComputeHash(passwordBytes.ToArray()).AsEnumerable();
|
||||
var passwordBytes = Encoding.UTF8.GetBytes(passphrase);
|
||||
|
||||
var hash = md5.ComputeHash(passwordBytes);
|
||||
cipherKey.AddRange(hash);
|
||||
|
||||
while (cipherKey.Count < length)
|
||||
{
|
||||
hash = passwordBytes.Concat(hash);
|
||||
|
||||
hash = md5.ComputeHash(hash.ToArray());
|
||||
|
||||
hash = passwordBytes.Concat(hash).ToArray();
|
||||
hash = md5.ComputeHash(hash);
|
||||
cipherKey.AddRange(hash);
|
||||
}
|
||||
}
|
||||
@@ -289,25 +318,22 @@ namespace Renci.SshNet
|
||||
if (binarySalt == null)
|
||||
throw new ArgumentNullException("binarySalt");
|
||||
|
||||
List<byte> cipherKey = new List<byte>();
|
||||
var cipherKey = new List<byte>();
|
||||
|
||||
using (var md5 = new MD5Hash())
|
||||
{
|
||||
var passwordBytes = Encoding.UTF8.GetBytes(passPhrase);
|
||||
|
||||
// Use 8 bytes binary salkt
|
||||
var initVector = passwordBytes.Concat(binarySalt.Take(8));
|
||||
|
||||
var hash = md5.ComputeHash(initVector.ToArray()).AsEnumerable();
|
||||
// Use 8 bytes binary salt
|
||||
var initVector = passwordBytes.Concat(binarySalt.Take(8)).ToArray();
|
||||
|
||||
var hash = md5.ComputeHash(initVector);
|
||||
cipherKey.AddRange(hash);
|
||||
|
||||
while (cipherKey.Count < cipherInfo.KeySize / 8)
|
||||
{
|
||||
hash = hash.Concat(initVector);
|
||||
|
||||
hash = md5.ComputeHash(hash.ToArray());
|
||||
|
||||
hash = hash.Concat(initVector).ToArray();
|
||||
hash = md5.ComputeHash(hash);
|
||||
cipherKey.AddRange(hash);
|
||||
}
|
||||
}
|
||||
@@ -401,7 +427,7 @@ namespace Renci.SshNet
|
||||
{
|
||||
var length = (int)base.ReadUInt32();
|
||||
|
||||
length = (int)(length + 7) / 8;
|
||||
length = (length + 7) / 8;
|
||||
|
||||
var data = base.ReadBytes(length);
|
||||
var bytesArray = new byte[data.Length + 1];
|
||||
|
||||
Reference in New Issue
Block a user