상속: ICipherParameters
예제 #1
0
        public static IDStorage decryptKeyStoreStorage(byte[] c_baKey, byte[] c_baIV, string c_sBase64JsonStorage)
        {
            const int MacBitSize = 128;
            byte [] baPayload = new byte[0];

            var decryptCipher = new GcmBlockCipher(new AesFastEngine());
            var parameters = new AeadParameters(new KeyParameter(c_baKey), MacBitSize, c_baIV, baPayload);
            decryptCipher.Init (false, parameters);

            byte[] baEncryptedStorage = Convert.FromBase64String (c_sBase64JsonStorage);

            var decryptedText = new byte[decryptCipher.GetOutputSize(baEncryptedStorage.Length)];
            try
            {
                var len = decryptCipher.ProcessBytes(baEncryptedStorage, 0, baEncryptedStorage.Length, decryptedText, 0);
                decryptCipher.DoFinal(decryptedText, len);
            }
            catch (InvalidCipherTextException)
            {
                //Return null if it doesn't authenticate
                return null;
            }

            string sJsonStorage = Encoding.GetEncoding (1252).GetString (decryptedText);
            IDStorage _KeyStoreStorage = JsonConvert.DeserializeObject <IDStorage> (sJsonStorage);

            return _KeyStoreStorage;
        }
예제 #2
0
        public JObject Encrypt(string key, JObject blob, string adata)
        {
            var result = new JObject();
            var random = new SecureRandom();

            var iv = new byte[32];
            var salt = new byte[8];

            random.NextBytes(salt);
            random.NextBytes(iv);

            try
            {
                byte[] plainBytes = Encoding.UTF8.GetBytes(blob.ToString());
                byte[] adataBytes = Encoding.UTF8.GetBytes(adata);
                byte[] nonce = ComputeNonce(iv, plainBytes);

                KeyParameter keyParam = CreateKey(key, salt, _iter, _ks);
                var ccm = new AeadParameters(keyParam, MacSize(_ts), nonce, adataBytes);

                var aes = new CcmBlockCipher(new AesFastEngine());
                aes.Init(true, ccm);

                var enc = new byte[aes.GetOutputSize(plainBytes.Length)];

                int res = aes.ProcessBytes(plainBytes, 0, plainBytes.Length, enc, 0);

                aes.DoFinal(enc, res);

                result.Add("ct", Base64.ToBase64String(enc));
                result.Add("iv", Base64.ToBase64String(iv));
                result.Add("salt", Base64.ToBase64String(salt));
                result.Add("adata", EncodeAdata(adata));
                result.Add("mode", Mode);
                result.Add("ks", _ks);
                result.Add("iter", _iter);
                result.Add("ts", _ts);

                return result;
            }
            catch (Exception e)
            {
                throw new ApplicationException("Json encryption failed.", e);
            }
        }
예제 #3
0
		/// <summary>
		/// Simple 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>
		public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null)
		{
			//User Error Checks
			if (key == null || key.Length != KeyBitSize / 8)
				throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");

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

			//Non-secret Payload Optional
			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 AesFastEngine());
			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();
			}
		}
예제 #4
0
		private GcmBlockCipher initCipher(
			IGcmMultiplier	m,
			bool			forEncryption,
			AeadParameters	parameters)
		{
			GcmBlockCipher c = new GcmBlockCipher(new AesFastEngine(), m);
			c.Init(forEncryption, parameters);
			return c;
		}
예제 #5
0
		private void runTestCase(
			string[]	testVector,
			int			macLength)
		{
			int pos = 0;
			string testName = testVector[pos++];
			byte[] K = Hex.Decode(testVector[pos++]);
			byte[] P = Hex.Decode(testVector[pos++]);
			byte[] A = Hex.Decode(testVector[pos++]);
			byte[] IV = Hex.Decode(testVector[pos++]);
			byte[] C = Hex.Decode(testVector[pos++]);

			// For short MAC, take leading bytes
			byte[] t = Hex.Decode(testVector[pos++]);
			byte[] T = new byte[macLength];
			Array.Copy(t, T, T.Length);

			AeadParameters parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, IV, A);

			// Default multiplier
			runTestCase(null, null, parameters, testName, P, C, T);

			runTestCase(new BasicGcmMultiplier(), new BasicGcmMultiplier(), parameters, testName, P, C, T);
			runTestCase(new Tables8kGcmMultiplier(), new Tables8kGcmMultiplier(), parameters, testName, P, C, T);
			runTestCase(new Tables64kGcmMultiplier(), new Tables64kGcmMultiplier(), parameters, testName, P, C, T);
		}
예제 #6
0
        private void checkVectors(
            int count,
            string additionalDataType,
            byte[] k,
            int macSize,
            byte[] n,
            byte[] a,
            byte[] sa,
            byte[] p,
            byte[] t,
            byte[] c)
        {
			EaxBlockCipher encEax = new EaxBlockCipher(new AesFastEngine());
			EaxBlockCipher decEax = new EaxBlockCipher(new AesFastEngine());

			AeadParameters parameters = new AeadParameters(new KeyParameter(k), macSize, n, a);
			encEax.Init(true, parameters);
			decEax.Init(false, parameters);

            runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c);
            runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c);

            // key reuse test
            parameters = new AeadParameters(null, macSize, n, a);
            encEax.Init(true, parameters);
            decEax.Init(false, parameters);

            runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c);
            runCheckVectors(count, encEax, decEax, additionalDataType, sa, p, t, c);
        }
예제 #7
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
        {
            byte[] nonce = new byte[this.encryptImplicitNonce.Length + nonce_explicit_length];
            Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length);

            /*
             * RFC 5288/6655 The nonce_explicit MAY be the 64-bit sequence number.
             * 
             * (May need review for other AEAD ciphers).
             */
            TlsUtilities.WriteUint64(seqNo, nonce, encryptImplicitNonce.Length);

            int plaintextOffset = offset;
            int plaintextLength = len;
            int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength);

            byte[] output = new byte[nonce_explicit_length + ciphertextLength];
            Array.Copy(nonce, encryptImplicitNonce.Length, output, 0, nonce_explicit_length);
            int outputPos = nonce_explicit_length;

            byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                encryptCipher.Init(true, parameters);
                outputPos += encryptCipher.ProcessBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos);
                outputPos += encryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return output;
        }
예제 #8
0
        private void RandomTest(SecureRandom srng)
        {
            int kLength = 16 + 8 * (System.Math.Abs(srng.NextInt()) % 3);
            byte[] K = new byte[kLength];
            srng.NextBytes(K);

            int pLength = (int)((uint)srng.NextInt() >> 16);
            byte[] P = new byte[pLength];
            srng.NextBytes(P);

            int aLength = (int)((uint)srng.NextInt() >> 24);
            byte[] A = new byte[aLength];
            srng.NextBytes(A);

            int saLength = (int)((uint)srng.NextInt() >> 24);
            byte[] SA = new byte[saLength];
            srng.NextBytes(SA);

            int ivLength = 1 + NextInt(srng, 15);
            byte[] IV = new byte[ivLength];
            srng.NextBytes(IV);

            AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A);
            IAeadBlockCipher cipher = InitOcbCipher(true, parameters);
            byte[] C = new byte[cipher.GetOutputSize(P.Length)];
            int predicted = cipher.GetUpdateOutputSize(P.Length);

            int split = NextInt(srng, SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            int len = cipher.ProcessBytes(P, 0, P.Length, C, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            if (predicted != len)
            {
                Fail("encryption reported incorrect update length in randomised test");
            }

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

            if (C.Length != len)
            {
                Fail("encryption reported incorrect length in randomised test");
            }

            byte[] encT = cipher.GetMac();
            byte[] tail = new byte[C.Length - P.Length];
            Array.Copy(C, P.Length, tail, 0, tail.Length);

            if (!AreEqual(encT, tail))
            {
                Fail("stream contained wrong mac in randomised test");
            }

            cipher.Init(false, parameters);
            byte[] decP = new byte[cipher.GetOutputSize(C.Length)];
            predicted = cipher.GetUpdateOutputSize(C.Length);

            split = NextInt(srng, SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            len = cipher.ProcessBytes(C, 0, C.Length, decP, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            if (predicted != len)
            {
                Fail("decryption reported incorrect update length in randomised test");
            }

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

            if (!AreEqual(P, decP))
            {
                Fail("incorrect decrypt in randomised test");
            }

            byte[] decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }

            //
            // key reuse test
            //
            cipher.Init(false, AeadTestUtilities.ReuseKey(parameters));
            decP = new byte[cipher.GetOutputSize(C.Length)];

            split = NextInt(srng, SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            len = cipher.ProcessBytes(C, 0, C.Length, decP, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

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

            if (!AreEqual(P, decP))
            {
                Fail("incorrect decrypt in randomised test");
            }

            decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }
        }
예제 #9
0
        private void OutputSizeTests()
        {
            byte[] K = new byte[16];
            byte[] A = null;
            byte[] IV = new byte[15];

            AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A);
            IAeadBlockCipher cipher = InitOcbCipher(true, parameters);

            if (cipher.GetUpdateOutputSize(0) != 0)
            {
                Fail("incorrect getUpdateOutputSize for initial 0 bytes encryption");
            }

            if (cipher.GetOutputSize(0) != 16)
            {
                Fail("incorrect getOutputSize for initial 0 bytes encryption");
            }

            cipher.Init(false, parameters);

            if (cipher.GetUpdateOutputSize(0) != 0)
            {
                Fail("incorrect getUpdateOutputSize for initial 0 bytes decryption");
            }

            // NOTE: 0 bytes would be truncated data, but we want it to fail in the doFinal, not here
            if (cipher.GetOutputSize(0) != 0)
            {
                Fail("fragile getOutputSize for initial 0 bytes decryption");
            }

            if (cipher.GetOutputSize(16) != 0)
            {
                Fail("incorrect getOutputSize for initial MAC-size bytes decryption");
            }
        }
예제 #10
0
        private void RunTestCase(string testName, string[] testVector, int macLengthBits, byte[] K)
        {
            int pos = 0;
            byte[] N = Hex.Decode(testVector[pos++]);
            byte[] A = Hex.Decode(testVector[pos++]);
            byte[] P = Hex.Decode(testVector[pos++]);
            byte[] C = Hex.Decode(testVector[pos++]);

            int macLengthBytes = macLengthBits / 8;

            KeyParameter keyParameter = new KeyParameter(K);
            AeadParameters parameters = new AeadParameters(keyParameter, macLengthBits, N, A);

            IAeadBlockCipher encCipher = InitOcbCipher(true, parameters);
            IAeadBlockCipher decCipher = InitOcbCipher(false, parameters);

            CheckTestCase(encCipher, decCipher, testName, macLengthBytes, P, C);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);
            encCipher.Init(true, keyReuseParams);
            decCipher.Init(false, keyReuseParams);
            CheckTestCase(encCipher, decCipher, testName + " (key reuse)", macLengthBytes, P, C);
        }
예제 #11
0
 private IAeadBlockCipher InitOcbCipher(bool forEncryption, AeadParameters parameters)
 {
     IAeadBlockCipher c = CreateOcbCipher();
     c.Init(forEncryption, parameters);
     return c;
 }
예제 #12
0
파일: OCBTest.cs 프로젝트: kyanha/bc-csharp
        private void RunTestCase(string testName, string[] testVector, int macLengthBits, byte[] K)
        {
            int pos = 0;
            byte[] N = Hex.Decode(testVector[pos++]);
            byte[] A = Hex.Decode(testVector[pos++]);
            byte[] P = Hex.Decode(testVector[pos++]);
            byte[] C = Hex.Decode(testVector[pos++]);

            int macLengthBytes = macLengthBits / 8;

            // TODO Variations processing AAD and cipher bytes incrementally

            KeyParameter keyParameter = new KeyParameter(K);
            AeadParameters aeadParameters = new AeadParameters(keyParameter, macLengthBits, N, A);

            IAeadBlockCipher encCipher = InitOcbCipher(true, aeadParameters);
            IAeadBlockCipher decCipher = InitOcbCipher(false, aeadParameters);

            CheckTestCase(encCipher, decCipher, testName, macLengthBytes, P, C);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C);

            // TODO Key reuse
        }
예제 #13
0
        private void RunTestCase(
            IGcmMultiplier  encM,
            IGcmMultiplier  decM,
            string          testName,
            byte[]          K,
            byte[]          IV,
            byte[]          A,
            byte[]          SA,
            byte[]          P,
            byte[]          C,
            byte[]          T)
        {
            AeadParameters parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, IV, A);
            GcmBlockCipher encCipher = InitCipher(encM, true, parameters);
            GcmBlockCipher decCipher = InitCipher(decM, false, parameters);
            CheckTestCase(encCipher, decCipher, testName, SA, P, C, T);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);
            encCipher.Init(true, keyReuseParams);
            decCipher.Init(false, keyReuseParams);
            CheckTestCase(encCipher, decCipher, testName + " (key reuse)", SA, P, C, T);
        }
예제 #14
0
        public static string encryptIdStorage(byte[] c_baKey, byte[] c_baIV, IDStorage c_KeyStoreStorage)
        {
            const int MacBitSize = 128;
            byte [] baPayload = new byte[0];

            var encryptCipher = new GcmBlockCipher(new AesFastEngine());
            var parameters = new AeadParameters(new KeyParameter(c_baKey), MacBitSize, c_baIV, baPayload);
            encryptCipher.Init (true, parameters);

            string sJsonStorage = JsonConvert.SerializeObject (c_KeyStoreStorage);//ConvertToJSON and
            byte[] baJsonStorage = Encoding.GetEncoding(1252).GetBytes(sJsonStorage);// get Bytes from ASCII-String

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

            string sCipherString = Convert.ToBase64String (cipherText);
            return sCipherString;
        }
예제 #15
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;
			}

		}
예제 #16
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len)
        {
            byte[] nonce = new byte[encryptImplicitNonce.Length + record_iv_length];

            switch (nonceMode)
            {
                case NONCE_RFC5288:
                    Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length);
                    // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
                    TlsUtilities.WriteUint64(seqNo, nonce, encryptImplicitNonce.Length);
                    break;
                case NONCE_DRAFT_CHACHA20_POLY1305:
                    TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
                    for (int i = 0; i < encryptImplicitNonce.Length; ++i)
                    {
                        nonce[i] ^= encryptImplicitNonce[i];
                    }
                    break;
                default:
                    throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            int plaintextOffset = offset;
            int plaintextLength = len;
            int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength);

            byte[] output = new byte[record_iv_length + ciphertextLength];
            if (record_iv_length != 0)
            {
                Array.Copy(nonce, nonce.Length - record_iv_length, output, 0, record_iv_length);
            }
            int outputPos = record_iv_length;

            byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                encryptCipher.Init(true, parameters);
                outputPos += encryptCipher.ProcessBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos);
                outputPos += encryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return output;
        }
예제 #17
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            if (GetPlaintextLimit(len) < 0)
                throw new TlsFatalAlert(AlertDescription.decode_error);

            byte[] nonce = new byte[this.decryptImplicitNonce.Length + nonce_explicit_length];
            Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length);
            Array.Copy(ciphertext, offset, nonce, decryptImplicitNonce.Length, nonce_explicit_length);

            int ciphertextOffset = offset + nonce_explicit_length;
            int ciphertextLength = len - nonce_explicit_length;
            int plaintextLength = decryptCipher.GetOutputSize(ciphertextLength);

            byte[] output = new byte[plaintextLength];
            int outputPos = 0;

            byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                decryptCipher.Init(false, parameters);
                outputPos += decryptCipher.ProcessBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos);
                outputPos += decryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return output;
        }
예제 #18
0
        /// <exception cref="IOException"></exception>
        public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len)
        {
            if (GetPlaintextLimit(len) < 0)
                throw new TlsFatalAlert(AlertDescription.decode_error);

            byte[] nonce = new byte[decryptImplicitNonce.Length + record_iv_length];

            switch (nonceMode)
            {
                case NONCE_RFC5288:
                    Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length);
                    Array.Copy(ciphertext, offset, nonce, nonce.Length - record_iv_length, record_iv_length);
                    break;
                case NONCE_DRAFT_CHACHA20_POLY1305:
                    TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8);
                    for (int i = 0; i < decryptImplicitNonce.Length; ++i)
                    {
                        nonce[i] ^= decryptImplicitNonce[i];
                    }
                    break;
                default:
                    throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            int ciphertextOffset = offset + record_iv_length;
            int ciphertextLength = len - record_iv_length;
            int plaintextLength = decryptCipher.GetOutputSize(ciphertextLength);

            byte[] output = new byte[plaintextLength];
            int outputPos = 0;

            byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength);
            AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData);

            try
            {
                decryptCipher.Init(false, parameters);
                outputPos += decryptCipher.ProcessBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos);
                outputPos += decryptCipher.DoFinal(output, outputPos);
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
            }

            if (outputPos != output.Length)
            {
                // NOTE: Existing AEAD cipher implementations all give exact output lengths
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            return output;
        }
예제 #19
0
        public JObject Decrypt(string key, JObject json)
        {
            try
            {
                byte[] iv = Base64.Decode(json.GetValue("iv").ToString());
                byte[] cipherText = Base64.Decode(json.GetValue("ct").ToString());
                byte[] adataBytes = DecodeAdataBytes(json.GetValue("adata").ToString());
                byte[] nonce = ComputeNonce(iv, cipherText);

                if (json.GetValue("mode").ToString() != "ccm")
                {
                    throw new ApplicationException("Can only decrypt ccm mode encrypted data.");
                }

                KeyParameter keyParam = CreateKey(
                    key,
                    Base64.Decode(json.GetValue("salt").ToString()),
                    json.GetValue("iter").ToObject<int>(),
                    json.GetValue("ks").ToObject<int>());

                var ccm = new AeadParameters(
                    keyParam,
                    MacSize(json.GetValue("ts").ToObject<int>()),
                    nonce,
                    adataBytes);

                var aes = new CcmBlockCipher(new AesFastEngine());
                aes.Init(false, ccm);

                var plainBytes = new byte[aes.GetOutputSize(cipherText.Length)];

                int res = aes.ProcessBytes(
                    cipherText,
                    0,
                    cipherText.Length,
                    plainBytes,
                    0);

                aes.DoFinal(plainBytes, res);
                var text = Encoding.UTF8.GetString(plainBytes);
                return JObject.Parse(text);
            }
            catch (InvalidCipherTextException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new ApplicationException("Json decryption failed.", e);
            }
        }
예제 #20
0
		protected override int Decrypt (DisposeContext d, ContentType contentType, IBufferOffsetSize input, IBufferOffsetSize output)
		{
			var implicitNonce = IsClient ? ServerWriteIV : ClientWriteIV;
			var writeKey = IsClient ? ServerWriteKey : ClientWriteKey;

			#if DEBUG_FULL
			if (Cipher.EnableDebugging) {
				DebugHelper.WriteLine ("FIXED IV", implicitNonce);
				DebugHelper.WriteLine ("WRITE KEY", writeKey);
				DebugHelper.WriteLine ("SEQUENCE: {0}", ReadSequenceNumber);
			}
			#endif

			var length = input.Size - ExplicitNonceSize;

			var aad = new TlsBuffer (13);
			aad.Write (ReadSequenceNumber);
			aad.Write ((byte)contentType);
			aad.Write ((short)Protocol);
			aad.Write ((short)(length - MacSize));

			#if DEBUG_FULL
			if (Cipher.EnableDebugging)
				DebugHelper.WriteFull ("TAG", aad);
			#endif

			var gcm = new GcmBlockCipher (new AesEngine ());
			var key = new KeyParameter (writeKey.Buffer);

			var nonce = d.CreateBuffer (ImplicitNonceSize + ExplicitNonceSize);
			Buffer.BlockCopy (implicitNonce.Buffer, 0, nonce.Buffer, 0, ImplicitNonceSize);
			Buffer.BlockCopy (input.Buffer, input.Offset, nonce.Buffer, ImplicitNonceSize, ExplicitNonceSize);

			#if DEBUG_FULL
			if (Cipher.EnableDebugging)
				DebugHelper.WriteLine ("NONCE", nonce);
			#endif

			var parameters = new AeadParameters (key, 128, nonce.Buffer, aad.Buffer);
			gcm.Init (false, parameters);

			int ret;
			try {
				ret = gcm.ProcessBytes (input.Buffer, input.Offset + ExplicitNonceSize, length, output.Buffer, output.Offset);

				ret += gcm.DoFinal (output.Buffer, output.Offset + ret);
			} catch (CryptoException ex) {
				throw new TlsException (AlertDescription.BadRecordMAC, ex.Message);
			}

			return ret;
		}
예제 #21
0
        private void checkVectors(
			int				count,
			byte[]			k,
			int				macSize,
			byte[]			n,
			byte[]			a,
			byte[]			p,
			byte[]			t,
			byte[]			c)
        {
            EaxBlockCipher encEax = new EaxBlockCipher(new AesFastEngine());
            EaxBlockCipher decEax = new EaxBlockCipher(new AesFastEngine());

            AeadParameters parameters = new AeadParameters(new KeyParameter(k), macSize, n, a);
            encEax.Init(true, parameters);
            decEax.Init(false, parameters);

            runCheckVectors(count, encEax, decEax, p, t, c);
            runCheckVectors(count, encEax, decEax, p, t, c);
        }
예제 #22
0
        public byte[] Decrypt(byte[] cipherBytes, int AddtnlAuthDataLength)
        {
            if (cipherBytes == null)
                return null;

            using (var cipherStream = new MemoryStream(cipherBytes))
            {
                using (var cipherReader = new BinaryReader(cipherStream))
                {
                    //Read Additional Authenticated Data (AddtnlAuthData)
                    var AddtnlAuthData = cipherReader.ReadBytes(AddtnlAuthDataLength);

                    byte[] clearBytes = null;
                    try 
                    {
                        // Read out IV
                        var IV = cipherReader.ReadBytes(IVBitSize / 8);

                        // Format AEAD parameters 
                        var parameters = new AeadParameters(keyParameter, TagBitSize, IV, AddtnlAuthData);
                        keyParameter = null;

                        cipher.Init(false, parameters);

                        // Read in cipher text, create output buffer
                        var encryptedBytes = cipherReader.ReadBytes(cipherBytes.Length - AddtnlAuthDataLength - IV.Length);
                        clearBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)];

                        // Decrypt ciphertext while verifying hmac
                        var len = cipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, clearBytes, 0);
                        cipher.DoFinal(clearBytes, len);
                    }
                    catch (Exception ex)
                    {
                        //Logger.Exception(ex);
                        if (ex is ArgumentException ||
                            ex is InvalidCipherTextException ||
                            ex is OverflowException)
                        {
                            return null; // this is null here
                        }
                        else
                        {
                            throw;
                        }
                    }

                    return clearBytes;
                }
            }
        }
예제 #23
0
		private void randomTest(
			SecureRandom srng)
		{
			int DAT_LEN = srng.Next(1024);
			byte[] nonce = new byte[NONCE_LEN];
			byte[] authen = new byte[AUTHEN_LEN];
			byte[] datIn = new byte[DAT_LEN];
			byte[] key = new byte[16];
			srng.NextBytes(nonce);
			srng.NextBytes(authen);
			srng.NextBytes(datIn);
			srng.NextBytes(key);

			AesFastEngine engine = new AesFastEngine();
			KeyParameter sessKey = new KeyParameter(key);
			EaxBlockCipher eaxCipher = new EaxBlockCipher(engine);

			AeadParameters parameters = new AeadParameters(sessKey, MAC_LEN * 8, nonce, authen);
			eaxCipher.Init(true, parameters);

			byte[] intrDat = new byte[eaxCipher.GetOutputSize(datIn.Length)];
			int outOff = eaxCipher.ProcessBytes(datIn, 0, DAT_LEN, intrDat, 0);
			outOff += eaxCipher.DoFinal(intrDat, outOff);

			eaxCipher.Init(false, parameters);
			byte[] datOut = new byte[eaxCipher.GetOutputSize(outOff)];
			int resultLen = eaxCipher.ProcessBytes(intrDat, 0, outOff, datOut, 0);
			eaxCipher.DoFinal(datOut, resultLen);

			if (!AreEqual(datIn, datOut))
			{
				Fail("EAX roundtrip failed to match");
			}
		}
예제 #24
0
        // encrypted = LSByte [AddtnlAuthData || IV || cipherOnly || hmac ] MSByte
        public byte[] Encrypt(byte[] plainBytes, byte[] AddtnlAuthData)
        {
            if (plainBytes == null)
                return null;

            // Additional Authenticated (but NOT encrypted) Data
            AddtnlAuthData = AddtnlAuthData ?? new byte[] { };

            // IV prep
            if (this.IV == null)
            {
                this.IV = new byte[IVBitSize / 8];
                Random.NextBytes(this.IV);
            }
            
            byte[] cipherBytes;
            try
            {
                var parameters = new AeadParameters(keyParameter, TagBitSize, IV, AddtnlAuthData);
                keyParameter = null;

                cipher.Init(true, parameters);

                //Generate Cipher Text With Auth Tag
                cipherBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
                var len = cipher.ProcessBytes(plainBytes, 0, plainBytes.Length, cipherBytes, 0);
                cipher.DoFinal(cipherBytes, len);
            }
            catch (Exception ex)
            {
                //Logger.Exception(ex);
                if (ex is ArgumentException ||
                    ex is InvalidCipherTextException ||
                    ex is OverflowException)
                {
                    return null; // this is null here
                }
                else
                {
                    throw;
                }
            }

            //Assemble Message
            using (var combinedStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(combinedStream))
                {
                    //Prepend Authenticated Payload
                    binaryWriter.Write(AddtnlAuthData);
                    //Prepend Nonce
                    binaryWriter.Write(IV);
                    //Write Cipher Text
                    binaryWriter.Write(cipherBytes);
                }
                return combinedStream.ToArray();
            }
        }
예제 #25
0
		private void runTestCase(
			IGcmMultiplier	encM,
			IGcmMultiplier	decM,
			AeadParameters	parameters,
			string			testName,
			byte[]			P,
			byte[]			C,
			byte[]			T)
		{
			GcmBlockCipher encCipher = initCipher(encM, true, parameters);
			GcmBlockCipher decCipher = initCipher(decM, false, parameters);
			checkTestCase(encCipher, decCipher, testName, P, C, T);
			checkTestCase(encCipher, decCipher, testName + " (reused)", P, C, T);
		}
예제 #26
0
 internal static AeadParameters ReuseKey(AeadParameters p)
 {
     return new AeadParameters(null, p.MacSize, p.GetNonce(), p.GetAssociatedText());
 }
예제 #27
0
		private void randomTest(
			SecureRandom	srng,
			IGcmMultiplier	m)
		{
			int kLength = 16 + 8 * srng.Next(3);
			byte[] K = new byte[kLength];
			srng.NextBytes(K);

			int pLength = srng.Next(1024);
			byte[] P = new byte[pLength];
			srng.NextBytes(P);

			int aLength = srng.Next(1024);
			byte[] A = new byte[aLength];
			srng.NextBytes(A);

			int ivLength = 1 + srng.Next(1024);
			byte[] IV = new byte[ivLength];
			srng.NextBytes(IV);

			GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine(), m);
			AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A);
			cipher.Init(true, parameters);
			byte[] C = new byte[cipher.GetOutputSize(P.Length)];
			int len = cipher.ProcessBytes(P, 0, P.Length, C, 0);
			len += cipher.DoFinal(C, len);

			if (C.Length != len)
			{
//				Console.WriteLine("" + C.Length + "/" + len);
				Fail("encryption reported incorrect length in randomised test");
			}

			byte[] encT = cipher.GetMac();
			byte[] tail = new byte[C.Length - P.Length];
			Array.Copy(C, P.Length, tail, 0, tail.Length);

			if (!AreEqual(encT, tail))
			{
				Fail("stream contained wrong mac in randomised test");
			}

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

			if (!AreEqual(P, decP))
			{
				Fail("incorrect decrypt in randomised test");
			}

			byte[] decT = cipher.GetMac();
			if (!AreEqual(encT, decT))
			{
				Fail("decryption produced different mac from encryption");
			}
		}
예제 #28
0
파일: OCBTest.cs 프로젝트: haf/bc-csharp
 private OcbBlockCipher InitCipher(bool forEncryption, AeadParameters parameters)
 {
     OcbBlockCipher c = new OcbBlockCipher(new AesFastEngine(), new AesFastEngine());
     c.Init(forEncryption, parameters);
     return c;
 }