Example #1
0
        public static string AesGcmDecrypt(string associatedData, string nonce, string ciphertext, string APIV3Key)
        {
            GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
            AeadParameters aeadParameters = new AeadParameters(
                new KeyParameter(Encoding.UTF8.GetBytes(APIV3Key)),
                128,
                Encoding.UTF8.GetBytes(nonce),
                Encoding.UTF8.GetBytes(associatedData));

            gcmBlockCipher.Init(false, aeadParameters);

            byte[] data      = Convert.FromBase64String(ciphertext);
            byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
            int    length    = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0);

            gcmBlockCipher.DoFinal(plaintext, length);
            return(Encoding.UTF8.GetString(plaintext));
        }
Example #2
0
        protected static string DecodeBytes(byte[] decodedBytes, Secret secret, int pbkdf2Iterations, Encoding encoding)
        {
#pragma warning disable CA1062
            var invalidCipherLength = decodedBytes.Length < MetaInfoLength;
#pragma warning restore CA1062
            s_helper.Check <StorageCryptoException>(invalidCipherLength, Messages.AesGcmCipher.s_errWrongEncryptedText);
            s_helper.Check <StorageCryptoException>(secret == null, Messages.AesGcmCipher.s_errNoSecret);
            s_helper.Check <StorageCryptoException>(encoding == null, Messages.AesGcmCipher.s_errNoEncoding);

            var salt = Arrays.CopyOfRange(decodedBytes, 0, SaltLength);
            var iv   = Arrays.CopyOfRange(decodedBytes, SaltLength, MetaInfoLength);

            var encrypted = Arrays.CopyOfRange(decodedBytes, MetaInfoLength, decodedBytes.Length);
            var key       = SecretKeyFactory.GetKey(salt, secret, pbkdf2Iterations);
            try
            {
                var cipher     = new GcmBlockCipher(new AesEngine());
                var parameters = new AeadParameters(new KeyParameter(key), AuthTagLengthInBits, iv, null);
                cipher.Init(false, parameters);

                var decryptedText = new byte[cipher.GetOutputSize(encrypted.Length)];

                var len = cipher.ProcessBytes(encrypted, 0, encrypted.Length, decryptedText, 0);
                cipher.DoFinal(decryptedText, len);
#pragma warning disable CA1062
                return(encoding.GetString(decryptedText));

#pragma warning restore CA1062
            }
            catch (InvalidCipherTextException ex)
            {
                s_log.Error(ex, Messages.AesGcmCipher.s_errInvalidCipher);
                throw new StorageCryptoException(Messages.AesGcmCipher.s_errInvalidCipher, ex);
            }
            catch (System.Exception ex)
            {
                s_log.Error(ex, Messages.AesGcmCipher.s_errUnexpectedDuringDecryption);
                throw new StorageCryptoException(Messages.AesGcmCipher.s_errUnexpectedDuringDecryption, ex);
            }
            finally
            {
                SecretKeyFactory.ShuffleSecretKey(key);
            }
        }
        public string Encrypt(string strToEncrypt, string passPhrase)
        {
            var plainText = Encoding.UTF8.GetBytes(strToEncrypt);
            var generator = new Pkcs5S2ParametersGenerator();
            var salt      = new byte[SaltBitSize / 8];

            Random.NextBytes(salt);

            generator.Init(
                PbeParametersGenerator.Pkcs5PasswordToBytes(passPhrase.ToCharArray()),
                salt,
                Iterations);

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

            var nonSecretPayload = new byte[] { };
            var payload          = new byte[salt.Length];

            Array.Copy(nonSecretPayload, payload, nonSecretPayload.Length);
            Array.Copy(salt, 0, payload, nonSecretPayload.Length, salt.Length);

            var nonce = new byte[NonceBitSize / 8];

            Random.NextBytes(nonce, 0, nonce.Length);

            var cipher     = new GcmBlockCipher(new AesEngine());
            var parameters = new AeadParameters(
                new KeyParameter(key.GetKey()), MacBitSize, nonce, payload);

            cipher.Init(true, parameters);

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

            cipher.DoFinal(cipherText, len);

            using var combinedStream = new MemoryStream();
            using var binaryWriter   = new BinaryWriter(combinedStream);
            binaryWriter.Write(payload);
            binaryWriter.Write(nonce);
            binaryWriter.Write(cipherText);

            return(Convert.ToBase64String(combinedStream.ToArray()));
        }
Example #4
0
        private string _decryptWithKey(byte[] message, byte[] key, int nonSecretPayloadLength)
        {
            const int KEY_BIT_SIZE   = 256;
            const int MAC_BIT_SIZE   = 128;
            const int NONCE_BIT_SIZE = 96;

            // data protected with DPAPI
            if (message[0] == 0x01 && message[1] == 0x00 && message[2] == 0x00 && message[3] == 0x00)
            {
                var decryptedData = ProtectedData.Unprotect(message, null, DataProtectionScope.CurrentUser);
                return(Encoding.Default.GetString(decryptedData));
            }

            if (key == null || key.Length != KEY_BIT_SIZE / 8)
            {
                throw new ArgumentException(String.Format("Key needs to be {0} bit!", KEY_BIT_SIZE), "key");
            }
            if (message == null || message.Length == 0)
            {
                throw new ArgumentException("Message required!", "message");
            }

            using (var cipherStream = new MemoryStream(message))
                using (var cipherReader = new BinaryReader(cipherStream))
                {
                    var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);
                    var nonce            = cipherReader.ReadBytes(NONCE_BIT_SIZE / 8);
                    var cipher           = new GcmBlockCipher(new AesEngine());
                    var parameters       = new AeadParameters(new KeyParameter(key), MAC_BIT_SIZE, nonce);
                    cipher.Init(false, parameters);
                    var cipherText = cipherReader.ReadBytes(message.Length);
                    var plainText  = new byte[cipher.GetOutputSize(cipherText.Length)];
                    try
                    {
                        var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
                        cipher.DoFinal(plainText, len);
                    }
                    catch (InvalidCipherTextException)
                    {
                        return(null);
                    }
                    return(Encoding.Default.GetString(plainText));
                }
        }
Example #5
0
        /// <summary>
        /// Encryption And Authentication (AES-GCM) of a UTF8 string.
        /// </summary>
        /// <param name="secretMessage">The secret message.</param>
        /// <param name="key">The key.</param>
        /// <param name="nonSecretPayload">Optional non-secret payload.</param>
        /// <returns>Encrypted Message</returns>
        /// <remarks>
        /// Adds overhead of (Optional-Payload + BlockSize(16) + Message +  HMac-Tag(16)) * 1.33 Base64
        /// </remarks>
        private static byte[] Encrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null)
        {
            // Key size check
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException($"Key needs to be {KeyBitSize} bit!", nameof(key));
            }

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

            // Using random nonce large enough not to repeat
            var nonce = new byte[NonceBitSize / 8];

            Random.NextBytes(nonce, 0, nonce.Length);

            var cipher     = new GcmBlockCipher(new AesEngine());
            var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);

            cipher.Init(true, parameters);

            // Generate Cipher Text With Auth Tag
            var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)];
            var len        = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);

            cipher.DoFinal(cipherText, len);

            // Assemble Message
            using (var combinedStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(combinedStream))
                {
                    // Prepend Authenticated Payload
                    binaryWriter.Write(nonSecretPayload);

                    // Prepend Nonce
                    binaryWriter.Write(nonce);

                    // Write Cipher Text
                    binaryWriter.Write(cipherText);
                }

                return(combinedStream.ToArray());
            }
        }
        /// <summary>
        /// Decryption & Authentication (AES-GCM) of a UTF8 Message
        /// </summary>
        /// <param name="encryptedMessage">The encrypted message.</param>
        /// <param name="key">The key.</param>
        /// <param name="nonSecretPayloadLength">Length of the optional non-secret payload.</param>
        /// <returns>Decrypted Message</returns>
        private byte[] AESGCMDecrypt(byte[] encryptedMessage, byte[] key)
        {
            // User Error Checks
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException(string.Format("Key needs to be {0} bit!", KeyBitSize), "key");
            }

            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))
                {
                    // Grab Nonce
                    var iv = cipherReader.ReadBytes(NonceBitSize / 8);

                    var cipher = new GcmBlockCipher(new AesEngine());

                    var keyParam = new KeyParameter(key);
                    ICipherParameters parameters = new ParametersWithIV(keyParam, iv);
                    cipher.Init(false, parameters);

                    // Decrypt Cipher Text
                    var cipherText = cipherReader.ReadBytes(encryptedMessage.Length - iv.Length);
                    var plainText  = new byte[cipher.GetOutputSize(cipherText.Length)];

                    try
                    {
                        var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
                        cipher.DoFinal(plainText, len);
                    }
                    catch (InvalidCipherTextException)
                    {
                        return(null);
                    }

                    return(plainText);
                }
            }
        }
Example #7
0
        /// <summary>
        /// Simple Decryption & Authentication (AES-GCM) of a UTF8 Message
        /// </summary>
        /// <param name="encryptedMessage">The encrypted message.</param>
        /// <param name="key">The key.</param>
        /// <param name="nonSecretPayloadLength">Length of the optional non-secret payload.</param>
        /// <returns>Decrypted Message</returns>
        public static byte[] SimpleDecrypt(byte[] encryptedMessage, byte[] key, int nonSecretPayloadLength = 0)
        {
            //User Error Checks
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");
            }

            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))
                {
                    //Grab Payload
                    var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);

                    //Grab Nonce
                    var nonce = cipherReader.ReadBytes(NonceBitSize / 8);

                    var cipher     = new GcmBlockCipher(new AesFastEngine());
                    var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);
                    cipher.Init(false, parameters);

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

                    try
                    {
                        var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
                        cipher.DoFinal(plainText, len);
                    }
                    catch (InvalidCipherTextException)
                    {
                        //Return null if it doesn't authenticate
                        return(null);
                    }

                    return(plainText);
                }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="InvalidCiphertextException"></exception>
        public byte[] DecryptName(byte[] input)
        {
            try
            {
                if (input.Length < 12 + 16 + 1)
                {
                    throw new InvalidCipherTextException($"Too short: {input.Length}");
                }

                byte[] nonce = new byte[12];
                Array.Copy(input, 0, nonce, 0, nonce.Length);

                GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine());
                cipher.Init(false, new AeadParameters(new KeyParameter(key), 128, nonce));

                byte[] paddedPlaintextOne = new byte[cipher.GetUpdateOutputSize(input.Length - 12)];
                cipher.ProcessBytes(input, 12, input.Length - 12, paddedPlaintextOne, 0);

                byte[] paddedPlaintextTwo = new byte[cipher.GetOutputSize(0)];
                cipher.DoFinal(paddedPlaintextTwo, 0);

                byte[] paddedPlaintext = ByteUtil.combine(paddedPlaintextOne, paddedPlaintextTwo);
                int    plaintextLength = 0;

                for (int i = paddedPlaintext.Length - 1; i >= 0; i--)
                {
                    if (paddedPlaintext[i] != 0x00)
                    {
                        plaintextLength = i + 1;
                        break;
                    }
                }

                byte[] plaintext = new byte[plaintextLength];
                Array.Copy(paddedPlaintext, 0, plaintext, 0, plaintextLength);

                return(plaintext);
            }
            catch (InvalidCipherTextException ex)
            {
                throw new InvalidCiphertextException(ex);
            }
        }
        public static byte[] EncryptAndDigest(string aad, byte[] data)
        {
            byte[] nonce    = Utilities.RandomBytes(12);
            byte[] aadBytes = Encoding.UTF8.GetBytes(aad);
            byte[] aadHash  = new SHA256Managed().ComputeHash(aadBytes);
            var    cipher   = new GcmBlockCipher(new AesEngine());
            var    cParams  = new AeadParameters(new KeyParameter(aadHash, 0, 16), 128, nonce, aadBytes);

            cipher.Init(true, cParams);
            byte[] ciphertext = new byte[cipher.GetOutputSize(data.Length)];
            int    retLen     = cipher.ProcessBytes(data, 0, data.Length, ciphertext, 0);

            cipher.DoFinal(ciphertext, retLen);

            byte[] output = new byte[nonce.Length + ciphertext.Length];
            Buffer.BlockCopy(nonce, 0, output, 0, nonce.Length);
            Buffer.BlockCopy(ciphertext, 0, output, nonce.Length, ciphertext.Length);
            return(output);
        }
Example #10
0
        public void aesGcmTest()
        {
            byte[] data       = { 8, 0, 6, 95, 31, 4, 0, 0, 0, 31, 1, 0, 0, 7 };
            byte[] authData   = { 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            var    MacBitSize = 96;

            byte[] iv = Security.getIv(new byte[] { 0x48, 0x58, 0x45, 0x03, 0x37, 0x4A, 0x1B, 0x08 }, 15582);
            lock (cipherLocker)
            {
                var cipher = new GcmBlockCipher(new AesEngine());
                cipher.Init(true, new AeadParameters(new KeyParameter(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), MacBitSize, iv));
                var cipherText = new byte[cipher.GetOutputSize(data.Length)];
                var len        = cipher.ProcessBytes(data, 0, data.Length, cipherText, 0);
                cipher.ProcessAadBytes(authData, 0, authData.Length);
                cipher.DoFinal(cipherText, len);
                byte[] expected = { 0x0D, 0xB6, 0x59, 0xB3, 0x0B, 0x7A, 0x91, 0x5C, 0x46, 0x9F, 0x01, 0x01, 0x83, 0x63, 0x1F, 0x20, 0xCB, 0x28, 0xD2, 0x6D, 0xD0, 0x5E, 0xC9, 0xB5, 0x2F, 0x6E };
                CollectionAssert.AreEqual(expected, cipherText);
            }
        }
Example #11
0
        public static string DecryptSymmetric(this string encrypted, string symmetricKey, string initialisationVector)
        {
            var       keyParameter = new KeyParameter(Convert.FromBase64String(symmetricKey));
            const int macSize      = 128;
            var       nonce        = new byte[128 / 8];

            nonce = Encoding.UTF8.GetBytes(initialisationVector).Take(nonce.Length).ToArray();
            var encdata        = Convert.FromBase64String(encrypted);
            var associatedText = new byte[] { };
            var cipher         = new GcmBlockCipher(new AesFastEngine());
            var parameters     = new AeadParameters(keyParameter, macSize, nonce, associatedText);

            cipher.Init(false, parameters);
            var msg = new byte[cipher.GetOutputSize(encdata.Length)];
            var len = cipher.ProcessBytes(encdata, 0, encdata.Length, msg, 0);

            cipher.DoFinal(msg, len);
            return(Encoding.UTF8.GetString(msg));
        }
 public static byte[] aesGcm(byte[] data, byte[] authData, CosemParameters parameters, int ivCounter)
 {
     try
     {
         byte[] iv = getIv(parameters.systemTitle, ivCounter);
         lock (cipherLocker)
         {
             var cipher = new GcmBlockCipher(new AesEngine());
             cipher.Init(true, new AeadParameters(new KeyParameter(parameters.ek), MacBitSize, iv));
             var cipherText = new byte[cipher.GetOutputSize(data.Length)];
             var len        = cipher.ProcessBytes(data, 0, data.Length, cipherText, 0);
             cipher.ProcessAadBytes(authData, 0, authData.Length);
             cipher.DoFinal(cipherText, len);
             return(cipherText);
         }
     }
     catch (InvalidKeyException e)
     {
         Console.WriteLine(e.ToString());
         Console.Write(e.StackTrace);
     }
     catch (InvalidParameterException e)
     {
         Console.WriteLine(e.ToString());
         Console.Write(e.StackTrace);
     }
     catch (CryptographicException e)
     {
         Console.WriteLine(e.ToString());
         Console.Write(e.StackTrace);
     }
     //catch (AEADBadTagException)
     //{
     //    throw new DlmsException(DlmsException.DlmsExceptionReason.SECURITY_FAIL);
     //}
     //catch (BadPaddingException e)
     //{
     //    Console.WriteLine(e.ToString());
     //    Console.Write(e.StackTrace);
     //}
     throw new DlmsException(DlmsException.DlmsExceptionReason.INTERNAL_ERROR);
 }
Example #13
0
        public static string Decrypt(byte[] encryptedBytes, byte[] key, byte[] iv)
        {
            string result = string.Empty;

            try
            {
                GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesFastEngine());
                AeadParameters parameters     = new AeadParameters(new KeyParameter(key), 128, iv, null);
                gcmBlockCipher.Init(forEncryption: false, parameters);
                byte[] array  = new byte[gcmBlockCipher.GetOutputSize(encryptedBytes.Length)];
                int    outOff = gcmBlockCipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, array, 0);
                gcmBlockCipher.DoFinal(array, outOff);
                result = Encoding.UTF8.GetString(array).TrimEnd("\r\n\0".ToCharArray());
                return(result);
            }
            catch
            {
                return(result);
            }
        }
        public byte[] Decrypt(byte[] secretText, byte[] cek, byte[] iv, byte[] aad, byte[] tag)
        {
            byte[] fullText = Utils.CombineArrays(secretText, tag);

            using (var cipherStream = new MemoryStream(fullText))
                using (var cipherReader = new BinaryReader(cipherStream))
                {
                    var cipher     = new GcmBlockCipher(new AesEngine());
                    var parameters = new AeadParameters(new KeyParameter(cek), KeySize, iv, aad);
                    cipher.Init(false, parameters);

                    var cipherText = cipherReader.ReadBytes(fullText.Length);
                    var plainText  = new byte[cipher.GetOutputSize(cipherText.Length)];

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

                    return(plainText);
                }
        }
        public static byte[] DecryptAndVerify(string aad, byte[] data)
        {
            byte[] nonce      = new byte[12];
            byte[] ciphertext = new byte[data.Length - 12];
            Buffer.BlockCopy(data, 0, nonce, 0, nonce.Length);
            Buffer.BlockCopy(data, nonce.Length, ciphertext, 0, ciphertext.Length);

            byte[] aadBytes = Encoding.UTF8.GetBytes(aad);
            byte[] aadHash  = new SHA256Managed().ComputeHash(aadBytes);
            var    cipher   = new GcmBlockCipher(new AesEngine());
            var    cParams  = new AeadParameters(new KeyParameter(aadHash, 0, 16), 128, nonce, aadBytes);

            cipher.Init(false, cParams);
            byte[] plaintext = new byte[cipher.GetOutputSize(ciphertext.Length)];
            int    retLen    = cipher.ProcessBytes(ciphertext, 0, ciphertext.Length, plaintext, 0);

            cipher.DoFinal(plaintext, retLen);

            return(plaintext);
        }
Example #16
0
        /// <summary>
        /// Decryption & Authentication (AES-GCM) of a UTF8 Message
        /// </summary>
        /// <param name="encryptedMessage">The encrypted message.</param>
        /// <param name="key">The key.</param>
        /// <param name="nonSecretPayloadLength">Length of the optional non-secret payload.</param>
        /// <returns>Decrypted Message</returns>
        private static byte[] Decrypt(byte[] encryptedMessage, byte[] key, int nonSecretPayloadLength = 0)
        {
            // Key size check
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException($"Key needs to be {KeyBitSize} bit!", nameof(key));
            }

            using (var cipherStream = new MemoryStream(encryptedMessage))
            {
                using (var cipherReader = new BinaryReader(cipherStream))
                {
                    // Grab Payload
                    var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);

                    // Grab Nonce
                    var nonce = cipherReader.ReadBytes(NonceBitSize / 8);

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

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

                    try
                    {
                        var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
                        cipher.DoFinal(plainText, len);
                    }
                    catch (InvalidCipherTextException)
                    {
                        // Return null if it doesn't authenticate
                        return(null);
                    }

                    return(plainText);
                }
            }
        }
Example #17
0
        public byte[] AesGcmDecrypt(ReadOnlySpan <byte> key, ReadOnlySpan <byte> ciphertext)
        {
            if (ciphertext.Length < AesGcmNonceSizeBytes + AesGcmTagSizeBytes)
            {
                throw new ArgumentException("Ciphertext is too short", nameof(ciphertext));
            }
            var cipher     = new GcmBlockCipher(new AesEngine());
            var nonce      = ciphertext.Slice(0, AesGcmNonceSizeBytes).ToArray();
            var parameters = new AeadParameters(
                new KeyParameter(key.ToArray()), AesGcmTagSizeBytes * 8, nonce, new byte[] {}
                );

            cipher.Init(false, parameters);

            var encrypted = ciphertext.Slice(AesGcmNonceSizeBytes).ToArray();
            var plaintext = new byte[cipher.GetOutputSize(encrypted.Length)];
            var len       = cipher.ProcessBytes(encrypted, 0, encrypted.Length, plaintext, 0);

            cipher.DoFinal(plaintext, len);
            return(plaintext);
        }
Example #18
0
        static readonly int GCM_TAG_LENGTH = 16;        //消息验证码tag的长度

        static byte[] encrypt(byte[] plaintext, byte[] key, byte[] iv)
        {
            var cipher     = new GcmBlockCipher(new AesEngine());
            var parameters = new AeadParameters(new KeyParameter(key), GCM_TAG_LENGTH * 8, iv, null);

            cipher.Init(true, parameters);
            var cipherText = new byte[cipher.GetOutputSize(plaintext.Length)];
            var len        = cipher.ProcessBytes(plaintext, 0, plaintext.Length, cipherText, 0);

            cipher.DoFinal(cipherText, len);
            Console.WriteLine("ciphertext:  " + Convert.ToBase64String(cipherText));

            byte[] cipherByte = new byte[cipherText.Length - 16]; //密文
            byte[] tagByte    = new byte[16];                     //tag
            Array.Copy(cipherText, cipherByte, cipherText.Length - 16);
            Console.WriteLine("cipher64:    " + Convert.ToBase64String(cipherByte));

            Array.Copy(cipherText, cipherText.Length - 16, tagByte, 0, 16);
            Console.WriteLine("tag64:    " + Convert.ToBase64String(tagByte));
            return(cipherText);
        }
Example #19
0
        /*
         * 解密算法
         */
        static byte[] decrypt(byte[] cipherText, byte[] key, byte[] iv)
        {
            var cipher     = new GcmBlockCipher(new AesEngine());
            var parameters = new AeadParameters(new KeyParameter(key), GCM_TAG_LENGTH * 8, iv, null);

            cipher.Init(false, parameters);
            //var cipherText = cipherReader.ReadBytes(message.Length - nonSecretPayloadLength - nonce.Length);
            var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];

            try
            {
                var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
                cipher.DoFinal(plainText, len);
            }
            catch (InvalidCipherTextException ex)
            {
                Console.WriteLine("InvalidCipherTextException:" + ex.Message);
            }
            Console.WriteLine("plaintext:   " + Encoding.UTF8.GetString(plainText));
            return(plainText);
        }
Example #20
0
        public byte[] Decrypt(byte[] data)
        {
            var daes = new GcmBlockCipher(new AesEngine());

            byte[] iv         = new byte[16];
            byte[] ciphertext = new byte[data.Length - iv.Length];

            Array.Copy(data, iv, iv.Length);
            Array.Copy(data, iv.Length, ciphertext, 0, ciphertext.Length);

            var parameters = new AeadParameters(_key, 128, iv);

            daes.Init(false, parameters);

            var final_message = new byte[daes.GetOutputSize(ciphertext.Length)];
            int len           = daes.ProcessBytes(ciphertext, 0, ciphertext.Length, final_message, 0);

            daes.DoFinal(final_message, len);

            return(final_message);
        }
Example #21
0
        public static byte[] EncryptMessage(KeyParameter sharedKey, byte[] nonSecretMessage, byte[] secretMessage)
        {
            if (nonSecretMessage != null && nonSecretMessage.Length > 255)
            {
                throw new Exception("Non Secret Message Too Long!");
            }
            byte nonSecretLength = nonSecretMessage == null ? (byte)0 : (byte)nonSecretMessage.Length;

            var nonce = new byte[NonceBitSize / 8];
            var rand  = new SecureRandom();

            rand.NextBytes(nonce, 0, nonce.Length);

            var cipher         = new GcmBlockCipher(new AesFastEngine());
            var aeadParameters = new AeadParameters(sharedKey, MacBitSize, nonce, nonSecretMessage);

            cipher.Init(true, aeadParameters);

            //Generate Cipher Text With Auth Tag
            var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)];
            var len        = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);

            cipher.DoFinal(cipherText, len);

            using (var combinedStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(combinedStream))
                {
                    //Prepend Authenticated Payload
                    binaryWriter.Write(nonSecretLength);
                    binaryWriter.Write(nonSecretMessage);

                    //Prepend Nonce
                    binaryWriter.Write(nonce);
                    //Write Cipher Text
                    binaryWriter.Write(cipherText);
                }
                return(combinedStream.ToArray());
            }
        }
Example #22
0
        public void AES_Decrypt(CBORObject alg, byte[] K)
        {
            GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine(), new BasicGcmMultiplier());
            KeyParameter   ContentKey;

            //  The requirements from JWA
            //  IV is 96 bits
            //  Authentication tag is 128 bits
            //  key sizes are 128, 192 and 256 bits

            ContentKey = new KeyParameter(K);

            byte[]     IV   = new byte[96 / 8];
            CBORObject cbor = FindAttribute(HeaderKeys.IV);

            if (cbor == null)
            {
                throw new Exception("Missing IV");
            }

            if (cbor.Type != CBORType.ByteString)
            {
                throw new CoseException("IV is incorrectly formed.");
            }
            if (cbor.GetByteString().Length > IV.Length)
            {
                throw new CoseException("IV is too long.");
            }
            Array.Copy(cbor.GetByteString(), 0, IV, IV.Length - cbor.GetByteString().Length, cbor.GetByteString().Length);

            AeadParameters parameters = new AeadParameters(ContentKey, 128, IV, getAADBytes());

            cipher.Init(false, parameters);
            byte[] C   = new byte[cipher.GetOutputSize(RgbEncrypted.Length)];
            int    len = cipher.ProcessBytes(RgbEncrypted, 0, RgbEncrypted.Length, C, 0);

            len += cipher.DoFinal(C, len);

            rgbContent = C;
        }
        /// <summary>
        /// Encryption And Authentication (AES-GCM) of a UTF8 string.
        /// </summary>
        /// <param name="strToken">Token to Encrypt.</param>
        /// <param name="key">The key.</param>
        /// <returns>Encrypted Message</returns>
        /// <remarks>
        /// Adds overhead of (Optional-Payload + BlockSize(16) + Message +  HMac-Tag(16)) * 1.33 Base64
        /// </remarks>
        private byte[] AESGCMEncrypt(byte[] strToken, byte[] key)
        {
            // User Error Checks
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException(string.Format("Key needs to be {0} bit!", KeyBitSize), "key");
            }

            // Using random nonce large enough not to repeat
            var iv = new byte[NonceBitSize / 8];

            Random.NextBytes(iv, 0, iv.Length);
            var cipher = new GcmBlockCipher(new AesEngine());

            // var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);
            var keyParam = new KeyParameter(key);
            ICipherParameters parameters = new ParametersWithIV(keyParam, iv);

            cipher.Init(true, parameters);

            // Generate Cipher Text With Auth Tag
            var cipherText = new byte[cipher.GetOutputSize(strToken.Length)];
            var len        = cipher.ProcessBytes(strToken, 0, strToken.Length, cipherText, 0);
            var len2       = cipher.DoFinal(cipherText, len);

            // Assemble Message
            using (var combinedStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(combinedStream))
                {
                    // Prepend Nonce
                    binaryWriter.Write(iv);

                    // Write Cipher Text
                    binaryWriter.Write(cipherText);
                }

                return(combinedStream.ToArray());
            }
        }
Example #24
0
        public byte[] EncryptWithKey(byte[] messageToEncrypt, byte[] key, byte[] nonSecretPayload = null)
        {
            //User Error Checks
            CheckKey(key);

            //Non-secret Payload Optional
            nonSecretPayload = nonSecretPayload ?? new byte[] { };

            //Using random nonce large enough not to repeat
            var nonce = new byte[_nonceSize / 8];

            _random.NextBytes(nonce, 0, nonce.Length);

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

            cipher.Init(true, parameters);

            //Generate Cipher Text With Auth Tag
            var cipherText = new byte[cipher.GetOutputSize(messageToEncrypt.Length)];
            var len        = cipher.ProcessBytes(messageToEncrypt, 0, messageToEncrypt.Length, cipherText, 0);

            cipher.DoFinal(cipherText, len);

            //Assemble Message
            using (var combinedStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(combinedStream))
                {
                    //Prepend Authenticated Payload
                    binaryWriter.Write(nonSecretPayload);
                    //Prepend Nonce
                    binaryWriter.Write(nonce);
                    //Write Cipher Text
                    binaryWriter.Write(cipherText);
                }
                return(combinedStream.ToArray());
            }
        }
        public static byte[] DecryptAesGcm(this byte[] encryptedMessage, byte[] key, int nonSecretPayloadLength = 0)
        {
            var keySize   = 256;
            var macSize   = 128;
            var nonceSize = 96;

            if (key == null || key.Length != keySize / 8)
            {
                throw new ArgumentException(String.Format("Key needs to be {0} bit! actual:{1}", keySize, key?.Length * 8), "key");
            }

            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))
                {
                    //Grab Payload
                    var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);

                    //Grab Nonce
                    var nonce = cipherReader.ReadBytes(nonceSize / 8);

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

                    //Decrypt Cipher Text
                    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(plainText);
                }
        }
Example #26
0
        //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
        #region --Set-, Get- Methods--


        #endregion
        //--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\
        #region --Misc Methods (Public)--
        public byte[] encrypt(byte[] data)
        {
            // Create the cipher instance and initialize:
            GcmBlockCipher cipher     = new GcmBlockCipher(new AesEngine());
            KeyParameter   keyParam   = new KeyParameter(key);
            AeadParameters aeadParams = new AeadParameters(keyParam, AUTH_TAG_SIZE_BITS, iv);

            cipher.Init(true, aeadParams);

            // Encrypt:
            byte[] ciphertext = new byte[cipher.GetOutputSize(data.Length)];
            int    length     = cipher.ProcessBytes(data, 0, data.Length, ciphertext, 0);

            cipher.DoFinal(ciphertext, length);
            authTag = cipher.GetMac();

            /*byte[] encryptedData = new byte[iv.Length + ciphertext.Length];
             * Buffer.BlockCopy(iv, 0, encryptedData, 0, iv.Length);
             * Buffer.BlockCopy(ciphertext, 0, encryptedData, iv.Length, ciphertext.Length);*/

            return(ciphertext);
        }
        private byte[] DecryptAesGcm(byte[] message, byte[] key, int nonSecretPayloadLength)
        {
            // TODO: Replace with .NET-own AES-GCM implementation in .NET Core 3.0+
            const int KEY_BIT_SIZE   = 256;
            const int MAC_BIT_SIZE   = 128;
            const int NONCE_BIT_SIZE = 96;

            if (key == null || key.Length != KEY_BIT_SIZE / 8)
            {
                throw new ArgumentException($"Key needs to be {KEY_BIT_SIZE} bit!", nameof(key));
            }
            if (message == null || message.Length == 0)
            {
                throw new ArgumentException("Message required!", nameof(message));
            }

            using (var cipherStream = new MemoryStream(message))
                using (var cipherReader = new BinaryReader(cipherStream))
                {
                    var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);
                    var nonce            = cipherReader.ReadBytes(NONCE_BIT_SIZE / 8);
                    var cipher           = new GcmBlockCipher(new AesEngine());
                    var parameters       = new AeadParameters(new KeyParameter(key), MAC_BIT_SIZE, nonce);
                    cipher.Init(false, parameters);
                    var cipherText = cipherReader.ReadBytes(message.Length);
                    var plainText  = new byte[cipher.GetOutputSize(cipherText.Length)];
                    try
                    {
                        var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
                        cipher.DoFinal(plainText, len);
                    }
                    catch (InvalidCipherTextException)
                    {
                        return(null);
                    }
                    return(plainText);
                }
        }
Example #28
0
        public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null)
        {
            if (key == null || key.Length != KeyBitSize / 8)
            {
                throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), nameof(key));
            }

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

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

            var nonce = new byte[NonceBitSize / 8];

            Random.NextBytes(nonce, 0, nonce.Length);

            var cipher     = new GcmBlockCipher(new AesFastEngine());
            var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);

            cipher.Init(true, parameters);

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

            cipher.DoFinal(cipherText, len);

            var combinedStream = new MemoryStream();

            using (var binaryWriter = new BinaryWriter(combinedStream))
            {
                binaryWriter.Write(nonSecretPayload);
                binaryWriter.Write(nonce);
                binaryWriter.Write(cipherText);
            }
            return(combinedStream.ToArray());
        }
Example #29
0
        private byte[] Decrypt(byte[] masterKey, byte[] iv, byte[] authKey, byte[] cipherText)
        {
            var input = new byte[cipherText.Length + authKey.Length];

            Array.Copy(cipherText, 0, input, 0, cipherText.Length);
            Array.Copy(authKey, 0, input, cipherText.Length, authKey.Length);


            var cipher     = new GcmBlockCipher(new AesEngine());
            var parameters =
                new AeadParameters(new KeyParameter(masterKey), 128, iv);

            cipher.Init(false, parameters);

            var output = new byte[cipher.GetOutputSize(input.Length)];

            var outputOffset = cipher.ProcessBytes
                                   (input, 0, input.Length, output, 0);

            cipher.DoFinal(output, outputOffset);

            return(output);
        }
Example #30
0
        private byte[] EncryptOrDecrypt(bool forEncryption, byte[] data, byte[] key, byte[] nonce)
        {
            if (ExpectedKeySize != key.Length)
            {
                throw new CryptoException("Invalid key size");
            }
            if (nonce.Length < 12) // A minimum of 96 bits is required
            {
                throw new CryptoException("Invalid nonce size");
            }

            ICipherParameters aeadParams = new AeadParameters(
                new KeyParameter(key), MacSizeBytes * 8, nonce, null);
            IAeadBlockCipher aesGcm = new GcmBlockCipher(new AesEngine());

            aesGcm.Init(forEncryption, aeadParams);

            byte[] result = new byte[aesGcm.GetOutputSize(data.Length)];
            int    len    = aesGcm.ProcessBytes(data, 0, data.Length, result, 0);

            aesGcm.DoFinal(result, len);
            return(result);
        }