<PackageReference Include="SSH.NET" Version="2024.0.0" />

Arc4Cipher

public sealed class Arc4Cipher : StreamCipher
Implements ARCH4 cipher algorithm.
using System; namespace Renci.SshNet.Security.Cryptography.Ciphers { public sealed class Arc4Cipher : StreamCipher { private const int STATE_LENGTH = 256; private byte[] _engineState; private int _x; private int _y; public override byte MinimumSize => 0; public Arc4Cipher(byte[] key, bool dischargeFirstBytes) : base(key) { SetKey(key); if (dischargeFirstBytes) Encrypt(new byte[1536]); } public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return ProcessBytes(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); } public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return ProcessBytes(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); } public override byte[] Encrypt(byte[] input, int offset, int length) { byte[] array = new byte[length]; ProcessBytes(input, offset, length, array, 0); return array; } public override byte[] Decrypt(byte[] input) { return Decrypt(input, 0, input.Length); } public override byte[] Decrypt(byte[] input, int offset, int length) { return Encrypt(input, offset, length); } private int ProcessBytes(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { if (inputOffset + inputCount > inputBuffer.Length) throw new ArgumentException("input buffer too short"); if (outputOffset + inputCount > outputBuffer.Length) throw new ArgumentException("output buffer too short"); for (int i = 0; i < inputCount; i++) { _x = ((_x + 1) & 255); _y = ((_engineState[_x] + _y) & 255); byte b = _engineState[_x]; _engineState[_x] = _engineState[_y]; _engineState[_y] = b; outputBuffer[i + outputOffset] = (byte)(inputBuffer[i + inputOffset] ^ _engineState[(_engineState[_x] + _engineState[_y]) & 255]); } return inputCount; } private void SetKey(byte[] keyBytes) { _x = 0; _y = 0; if (_engineState == null) _engineState = new byte[256]; for (int i = 0; i < 256; i++) { _engineState[i] = (byte)i; } int num = 0; int num2 = 0; for (int j = 0; j < 256; j++) { num2 = (((keyBytes[num] & 255) + _engineState[j] + num2) & 255); byte b = _engineState[j]; _engineState[j] = _engineState[num2]; _engineState[num2] = b; num = (num + 1) % keyBytes.Length; } } } }