SSH1UserAuthKey.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:4k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2.  Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3.  This file is a part of the Granados SSH Client Library that is subject to
  4.  the license included in the distributed package.
  5.  You may not use this file except in compliance with the license.
  6.  $Id: SSH1UserAuthKey.cs,v 1.2 2005/04/20 08:58:56 okajima Exp $
  7. */
  8. using System;
  9. using System.IO;
  10. using System.Text;
  11. using System.Security.Cryptography;
  12. using System.Diagnostics;
  13. using Granados.SSHC;
  14. namespace Granados.SSHCV1
  15. {
  16. /// <summary>
  17. /// private key for user authentication
  18. /// </summary>
  19. public class SSH1UserAuthKey
  20. {
  21. private BigInteger _modulus;
  22. private BigInteger _publicExponent;
  23. private BigInteger _privateExponent;
  24. private BigInteger _primeP;
  25. private BigInteger _primeQ;
  26. private BigInteger _crtCoefficient;
  27. public BigInteger PublicModulus {
  28. get {
  29. return _modulus;
  30. }
  31. }
  32. public BigInteger PublicExponent {
  33. get {
  34. return _publicExponent;
  35. }
  36. }
  37. /// <summary>
  38. /// constructs from file
  39. /// </summary>
  40. /// <param name="path">file name</param>
  41. /// <param name="passphrase">passphrase or empty string if passphrase is not required</param>
  42. public SSH1UserAuthKey(string path, string passphrase)
  43. {
  44. Stream s = File.Open(path, FileMode.Open);
  45. byte[] header = new byte[32];
  46. s.Read(header, 0, header.Length);
  47. if(Encoding.ASCII.GetString(header)!="SSH PRIVATE KEY FILE FORMAT 1.1n")
  48. throw new SSHException(String.Format(Strings.GetString("BrokenKeyFile"), path));
  49. SSH1DataReader reader = new SSH1DataReader(ReadAll(s));
  50. s.Close();
  51. byte[] cipher = reader.Read(2); //first 2 bytes indicates algorithm and next 8 bytes is space
  52. reader.Read(8);
  53. _modulus = reader.ReadMPInt();
  54. _publicExponent = reader.ReadMPInt();
  55. byte[] comment = reader.ReadString();
  56. byte[] prvt = reader.ReadAll();
  57. //昁梫側傜暅崋
  58. CipherAlgorithm algo = (CipherAlgorithm)cipher[1];
  59. if(algo!=0) {
  60. Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, ConvertToKey(passphrase));
  61. byte[] buf = new byte[prvt.Length];
  62. c.Decrypt(prvt, 0, prvt.Length, buf, 0);
  63. prvt = buf;
  64. }
  65. SSH1DataReader prvtreader = new SSH1DataReader(prvt);
  66. byte[] mark = prvtreader.Read(4);
  67. if(mark[0]!=mark[2] || mark[1]!=mark[3])
  68. throw new SSHException(Strings.GetString("WrongPassphrase"));
  69. _privateExponent = prvtreader.ReadMPInt();
  70. _crtCoefficient = prvtreader.ReadMPInt();
  71. _primeP = prvtreader.ReadMPInt();
  72. _primeQ = prvtreader.ReadMPInt();
  73. }
  74. public BigInteger decryptChallenge(BigInteger encryptedchallenge) {
  75. BigInteger primeExponentP = PrimeExponent(_privateExponent, _primeP);
  76. BigInteger primeExponentQ = PrimeExponent(_privateExponent, _primeQ);
  77. BigInteger p2;
  78. BigInteger q2;
  79. BigInteger k;
  80. BigInteger result;
  81. p2 = encryptedchallenge % _primeP;
  82. p2 = p2.modPow(primeExponentP, _primeP);
  83. q2 = encryptedchallenge % _primeQ;
  84. q2 = q2.modPow(primeExponentQ, _primeQ);
  85. if(p2==q2) return p2;
  86. k = (q2 - p2) % _primeQ;
  87. if(k.IsNegative) k += _primeQ;
  88. k = k * _crtCoefficient;
  89. k = k % _primeQ;
  90. result = k * _primeP;
  91. result = result + p2;
  92. return result;
  93. }
  94. private static BigInteger PrimeExponent(BigInteger privateExponent, BigInteger prime) {
  95. BigInteger pe = prime - new BigInteger(1);
  96. return privateExponent % pe;
  97. }
  98. private static byte[] ReadAll(Stream s) {
  99. byte[] t = new byte[0x1000];
  100. int l = s.Read(t, 0, 0x1000);
  101. if(l==t.Length) throw new IOException("Key file is too big");
  102. return t;
  103. }
  104. //key from passphrase
  105. private static byte[] ConvertToKey(string passphrase) {
  106. byte[] t = Encoding.ASCII.GetBytes(passphrase);
  107. byte[] md5 = new MD5CryptoServiceProvider().ComputeHash(t);
  108. byte[] result = new byte[32];
  109. Array.Copy(md5, 0, result, 0, 16);
  110. Array.Copy(md5, 0, result, 16, 16);
  111. return result;
  112. }
  113. }
  114. }