CipherDigitalSignature.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Security.Cryptography;
  6. using Renci.SshNet.Common;
  7. namespace Renci.SshNet.Security.Cryptography
  8. {
  9. /// <summary>
  10. /// Implements digital signature where where asymmetric cipher is used,
  11. /// </summary>
  12. public abstract class CipherDigitalSignature : DigitalSignature
  13. {
  14. private AsymmetricCipher _cipher;
  15. private ObjectIdentifier _oid;
  16. /// <summary>
  17. /// Initializes a new instance of the <see cref="CipherDigitalSignature"/> class.
  18. /// </summary>
  19. /// <param name="oid">The object identifier.</param>
  20. /// <param name="cipher">The cipher.</param>
  21. public CipherDigitalSignature(ObjectIdentifier oid, AsymmetricCipher cipher)
  22. {
  23. if (cipher == null)
  24. throw new ArgumentNullException("cipher");
  25. this._cipher = cipher;
  26. this._oid = oid;
  27. }
  28. /// <summary>
  29. /// Verifies the signature.
  30. /// </summary>
  31. /// <param name="input">The input.</param>
  32. /// <param name="signature">The signature.</param>
  33. /// <returns></returns>
  34. public override bool Verify(byte[] input, byte[] signature)
  35. {
  36. var encryptedSignature = this._cipher.Decrypt(signature);
  37. var hashData = this.Hash(input);
  38. var expected = DerEncode(hashData);
  39. if (expected.SequenceEqual(encryptedSignature))
  40. return true;
  41. else
  42. return false;
  43. }
  44. /// <summary>
  45. /// Creates the signature.
  46. /// </summary>
  47. /// <param name="input">The input.</param>
  48. /// <returns></returns>
  49. public override byte[] Sign(byte[] input)
  50. {
  51. // Calculate hash value
  52. var hashData = this.Hash(input);
  53. // Calculate DER string
  54. var derEncodedHash = DerEncode(hashData);
  55. return this._cipher.Encrypt(derEncodedHash).TrimLeadingZero().ToArray();
  56. }
  57. /// <summary>
  58. /// Hashes the specified input.
  59. /// </summary>
  60. /// <param name="input">The input.</param>
  61. /// <returns></returns>
  62. protected abstract byte[] Hash(byte[] input);
  63. /// <summary>
  64. /// Encodes hash using DER.
  65. /// </summary>
  66. /// <param name="hashData">The hash data.</param>
  67. /// <returns>DER Encoded byte array</returns>
  68. protected byte[] DerEncode(byte[] hashData)
  69. {
  70. var data = new DerData();
  71. var alg = new DerData();
  72. alg.Write(this._oid);
  73. alg.WriteNull();
  74. data.Write(alg);
  75. data.Write(hashData);
  76. return data.Encode();
  77. }
  78. }
  79. }