Cipher.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System;
  4. using Renci.SshNet.Security.Cryptography;
  5. namespace Renci.SshNet.Security
  6. {
  7. /// <summary>
  8. /// Represents the abstract base class from which all implementations of cipher must inherit.
  9. /// </summary>
  10. public abstract class Cipher : Algorithm
  11. {
  12. private ModeBase _encryptor;
  13. private ModeBase _decryptor;
  14. /// <summary>
  15. /// Gets or sets the block size, in bits, of the cipher operation.
  16. /// </summary>
  17. /// <value>
  18. /// The block size, in bits.
  19. /// </value>
  20. public abstract int BlockSize { get; }
  21. /// <summary>
  22. /// Gets or sets the key size, in bits, of the secret key used by the cipher.
  23. /// </summary>
  24. /// <value>
  25. /// The key size, in bits.
  26. /// </value>
  27. public abstract int KeySize { get; }
  28. /// <summary>
  29. /// Gets the secret key for the cipher.
  30. /// </summary>
  31. protected byte[] Key { get; private set; }
  32. /// <summary>
  33. /// Gets the initialization vector (IV) for the cipher.
  34. /// </summary>
  35. protected byte[] Vector { get; private set; }
  36. /// <summary>
  37. /// Initializes the cipher.
  38. /// </summary>
  39. /// <param name="key">The secret key.</param>
  40. /// <param name="vector">The initialization vector.</param>
  41. public virtual void Init(IEnumerable<byte> key, IEnumerable<byte> vector)
  42. {
  43. this.Key = key.ToArray();
  44. this.Vector = vector.ToArray();
  45. }
  46. /// <summary>
  47. /// Encrypts the specified data.
  48. /// </summary>
  49. /// <param name="data">The data.</param>
  50. /// <returns>Encrypted data</returns>
  51. public byte[] Encrypt(byte[] data)
  52. {
  53. if (this._encryptor == null)
  54. {
  55. this._encryptor = this.CreateEncryptor();
  56. }
  57. var output = new byte[data.Length];
  58. if (data.Length % this.BlockSize > 0)
  59. throw new ArgumentException("data");
  60. var writtenBytes = 0;
  61. for (int i = 0; i < data.Length / this.BlockSize; i++)
  62. {
  63. writtenBytes += this._encryptor.EncryptBlock(data, i * this.BlockSize, this.BlockSize, output, i * this.BlockSize);
  64. }
  65. if (writtenBytes < data.Length)
  66. {
  67. throw new InvalidOperationException("Encryption error.");
  68. }
  69. return output;
  70. }
  71. /// <summary>
  72. /// Decrypts the specified data.
  73. /// </summary>
  74. /// <param name="data">The data.</param>
  75. /// <returns>Decrypted data</returns>
  76. public byte[] Decrypt(byte[] data)
  77. {
  78. if (this._decryptor == null)
  79. {
  80. this._decryptor = this.CreateDecryptor();
  81. }
  82. var output = new byte[data.Length];
  83. if (data.Length % this.BlockSize > 0)
  84. throw new ArgumentException("data");
  85. var writtenBytes = 0;
  86. for (int i = 0; i < data.Length / this.BlockSize; i++)
  87. {
  88. writtenBytes += this._decryptor.DecryptBlock(data, i * this.BlockSize, this.BlockSize, output, i * this.BlockSize);
  89. }
  90. if (writtenBytes < data.Length)
  91. {
  92. throw new InvalidOperationException("Encryption error.");
  93. }
  94. return output;
  95. }
  96. /// <summary>
  97. /// Creates the encryptor.
  98. /// </summary>
  99. /// <returns></returns>
  100. protected abstract ModeBase CreateEncryptor();
  101. /// <summary>
  102. /// Creates the decryptor.
  103. /// </summary>
  104. /// <returns></returns>
  105. protected abstract ModeBase CreateDecryptor();
  106. }
  107. }