AesCipher.cs 4.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System;
  2. using System.Security.Cryptography;
  3. namespace Renci.SshNet.Security.Cryptography.Ciphers
  4. {
  5. /// <summary>
  6. /// AES cipher implementation.
  7. /// </summary>
  8. public sealed class AesCipher : BlockCipher, IDisposable
  9. {
  10. private readonly Aes _aes;
  11. private ICryptoTransform _encryptor;
  12. private ICryptoTransform _decryptor;
  13. /// <summary>
  14. /// Initializes a new instance of the <see cref="AesCipher"/> class.
  15. /// </summary>
  16. /// <param name="key">The key.</param>
  17. /// <param name="mode">The mode.</param>
  18. /// <param name="padding">The padding.</param>
  19. /// <exception cref="ArgumentNullException"><paramref name="key"/> is <see langword="null"/>.</exception>
  20. /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
  21. public AesCipher(byte[] key, CipherMode mode, CipherPadding padding)
  22. : base(key, 16, mode, padding)
  23. {
  24. var aes = Aes.Create();
  25. aes.Key = key;
  26. #pragma warning disable CA5358 // Do not use unsafe cipher modes; this is the basis for other modes.
  27. aes.Mode = System.Security.Cryptography.CipherMode.ECB;
  28. #pragma warning restore CA5358 // Do not use unsafe cipher modes
  29. aes.Padding = PaddingMode.None;
  30. _aes = aes;
  31. }
  32. /// <summary>
  33. /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
  34. /// </summary>
  35. /// <param name="inputBuffer">The input data to encrypt.</param>
  36. /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
  37. /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
  38. /// <param name="outputBuffer">The output to which to write encrypted data.</param>
  39. /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
  40. /// <returns>
  41. /// The number of bytes encrypted.
  42. /// </returns>
  43. /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is <see langword="null"/>.</exception>
  44. /// <exception cref="ArgumentException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is too short.</exception>
  45. public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  46. {
  47. _encryptor ??= _aes.CreateEncryptor();
  48. return _encryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  49. }
  50. /// <summary>
  51. /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
  52. /// </summary>
  53. /// <param name="inputBuffer">The input data to decrypt.</param>
  54. /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
  55. /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
  56. /// <param name="outputBuffer">The output to which to write decrypted data.</param>
  57. /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
  58. /// <returns>
  59. /// The number of bytes decrypted.
  60. /// </returns>
  61. /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is <see langword="null"/>.</exception>
  62. /// <exception cref="IndexOutOfRangeException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is too short.</exception>
  63. public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  64. {
  65. _decryptor ??= _aes.CreateDecryptor();
  66. return _decryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  67. }
  68. private void Dispose(bool disposing)
  69. {
  70. if (disposing)
  71. {
  72. _encryptor?.Dispose();
  73. _encryptor = null;
  74. _decryptor?.Dispose();
  75. _decryptor = null;
  76. }
  77. }
  78. /// <inheritdoc/>
  79. public void Dispose()
  80. {
  81. // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
  82. Dispose(disposing: true);
  83. GC.SuppressFinalize(this);
  84. }
  85. }
  86. }