Шифрование / дешифрование AES GCM в c# с помощью BouncyCastle - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь кодировать и декодировать с помощью библиотеки BounceCastle в c# некоторые данные с паролем, но я получаю сообщение об ошибке в методе расшифровки при вызове cipher.DoFinal(cipherText, len)

Ошибка:

"mac check in GCM failed"

Вот код:

public string DecryptWithKey(byte[] encryptedMessage, string password, int nonSecretPayloadLength = 0)
    {
        var generator = new Pkcs5S2ParametersGenerator();

        var salt = new byte[20 / 8];

        generator.Init(
          PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
          salt,
          65556);

        var key = (KeyParameter)generator.GenerateDerivedMacParameters(_keySize);

        if (encryptedMessage == null || encryptedMessage.Length == 0)
        {
            throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");
        }

        using (var cipherStream = new MemoryStream(encryptedMessage))
        using (var cipherReader = new BinaryReader(cipherStream))
        {
            var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);
            var nonce = cipherReader.ReadBytes(_nonceSize / 8);

            var cipher = new GcmBlockCipher(new AesEngine());
            var parameters = new AeadParameters(key, _macSize, nonce, nonSecretPayload);
            cipher.Init(false, parameters);

            var cipherText = cipherReader.ReadBytes(encryptedMessage.Length - nonSecretPayloadLength - nonce.Length);
            var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];

            var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
            cipher.DoFinal(plainText, len);

            return Encoding.UTF8.GetString(plainText, 0, plainText.Length);
        }
    }

    public byte[] EncryptWithKey(string message, string password, byte[] nonSecretPayload = null)
    {
        var generator = new Pkcs5S2ParametersGenerator();

        var salt = new byte[20 / 8];

        generator.Init(
          PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
          salt,
          65556);

        var key = (KeyParameter)generator.GenerateDerivedMacParameters(_keySize);

        var messageToEncrypt = Encoding.UTF8.GetBytes(message);

        nonSecretPayload = nonSecretPayload ?? new byte[] { };

        var nonce = new byte[_nonceSize / 8];
        _random.NextBytes(nonce);

        var cipher = new GcmBlockCipher(new AesEngine());
        var parameters = new AeadParameters(key, _macSize, nonce, nonSecretPayload);
        cipher.Init(true, parameters);

        var cipherText = new byte[cipher.GetOutputSize(messageToEncrypt.Length)];
        var len = cipher.ProcessBytes(messageToEncrypt, 0, messageToEncrypt.Length, cipherText, 0);
        cipher.DoFinal(cipherText, len);

        using (var combinedStream = new MemoryStream())
        {
            using (var binaryWriter = new BinaryWriter(combinedStream))
            {
                binaryWriter.Write(nonSecretPayload);
                binaryWriter.Write(nonce);
                binaryWriter.Write(cipherText);
            }
            return combinedStream.ToArray();
        }
    }
}

Эти значения в переменных инициализированы:

_keySize = 256
_macSize = 128
_nonceSize = 128

nonSecretPayloadLength = 0
nonSecretPayload = null 
...