Пример #1
0
        public void TestEax()
        {
            byte[] K = Hex.Decode("233952DEE4D5ED5F9B9C6D6FF80FF478");
            byte[] N = Hex.Decode("62EC67F9C3A4A407FCB2A8C49031A8B3");
            byte[] P = Hex.Decode("68656c6c6f20776f726c642121");
            byte[] C = Hex.Decode("2f9f76cb7659c70e4be11670a3e193ae1bc6b5762a");

            KeyParameter    key       = ParameterUtilities.CreateKeyParameter("AES", K);
            IBufferedCipher inCipher  = CipherUtilities.GetCipher("AES/EAX/NoPadding");
            IBufferedCipher outCipher = CipherUtilities.GetCipher("AES/EAX/NoPadding");

            inCipher.Init(true, new ParametersWithIV(key, N));

            byte[] enc = inCipher.DoFinal(P);
            if (!AreEqual(enc, C))
            {
                Fail("ciphertext doesn't match in EAX");
            }

            outCipher.Init(false, new ParametersWithIV(key, N));

            byte[] dec = outCipher.DoFinal(C);
            if (!AreEqual(dec, P))
            {
                Fail("plaintext doesn't match in EAX");
            }

            try
            {
                inCipher = CipherUtilities.GetCipher("AES/EAX/PKCS5Padding");

                Fail("bad padding missed in EAX");
            }
            catch (SecurityUtilityException)
            {
                // expected
            }
        }
        /// <summary>
        /// Generate an enveloped object that contains an CMS Enveloped Data
        /// object using the passed in key generator.
        /// </summary>
        private Stream Open(
            Stream outStream,
            string encryptionOid,
            CipherKeyGenerator keyGen)
        {
            byte[]       encKeyBytes = keyGen.GenerateKey();
            KeyParameter encKey      = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes);

            Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes);

            ICipherParameters   cipherParameters;
            AlgorithmIdentifier encAlgID = GetAlgorithmIdentifier(
                encryptionOid, encKey, asn1Params, out cipherParameters);

            Asn1EncodableVector recipientInfos = new Asn1EncodableVector();

            foreach (RecipientInf recipient in recipientInfs)
            {
                try
                {
                    recipientInfos.Add(recipient.ToRecipientInfo(encKey, rand));
                }
                catch (IOException e)
                {
                    throw new CmsException("encoding error.", e);
                }
                catch (InvalidKeyException e)
                {
                    throw new CmsException("key inappropriate for algorithm.", e);
                }
                catch (GeneralSecurityException e)
                {
                    throw new CmsException("error making encrypted content.", e);
                }
            }

            return(Open(outStream, encAlgID, cipherParameters, recipientInfos));
        }
Пример #3
0
        private KeyParameter CalculateAgreedWrapKey(
            string wrapAlg,
            AsymmetricKeyParameter senderPublicKey,
            AsymmetricKeyParameter receiverPrivateKey)
        {
            DerObjectIdentifier agreeAlgID = keyEncAlg.Algorithm;

            ICipherParameters senderPublicParams    = senderPublicKey;
            ICipherParameters receiverPrivateParams = receiverPrivateKey;

            if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
            {
                byte[] ukmEncoding        = info.UserKeyingMaterial.GetOctets();
                MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance(
                    Asn1Object.FromByteArray(ukmEncoding));

                AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey(
                    receiverPrivateKey, ukm.EphemeralPublicKey);

                senderPublicParams = new MqvPublicParameters(
                    (ECPublicKeyParameters)senderPublicParams,
                    (ECPublicKeyParameters)ephemeralKey);
                receiverPrivateParams = new MqvPrivateParameters(
                    (ECPrivateKeyParameters)receiverPrivateParams,
                    (ECPrivateKeyParameters)receiverPrivateParams);
            }

            IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf(
                agreeAlgID, wrapAlg);

            agreement.Init(receiverPrivateParams);
            BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams);

            int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;

            byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize);
            return(ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes));
        }
        private KeyParameter CalculateAgreedWrapKey(string wrapAlg, AsymmetricKeyParameter senderPublicKey, AsymmetricKeyParameter receiverPrivateKey)
        {
            DerObjectIdentifier objectID          = this.keyEncAlg.ObjectID;
            ICipherParameters   cipherParameters  = senderPublicKey;
            ICipherParameters   cipherParameters2 = receiverPrivateKey;

            if (objectID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
            {
                byte[] octets = this.info.UserKeyingMaterial.GetOctets();
                MQVuserKeyingMaterial  instance = MQVuserKeyingMaterial.GetInstance(Asn1Object.FromByteArray(octets));
                AsymmetricKeyParameter publicKeyFromOriginatorPublicKey = this.GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, instance.EphemeralPublicKey);
                cipherParameters  = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters, (ECPublicKeyParameters)publicKeyFromOriginatorPublicKey);
                cipherParameters2 = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters2, (ECPrivateKeyParameters)cipherParameters2);
            }
            IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(objectID, wrapAlg);

            basicAgreementWithKdf.Init(cipherParameters2);
            BigInteger s       = basicAgreementWithKdf.CalculateAgreement(cipherParameters);
            int        qLength = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;

            byte[] keyBytes = X9IntegerConverter.IntegerToBytes(s, qLength);
            return(ParameterUtilities.CreateKeyParameter(wrapAlg, keyBytes));
        }
        public static byte[] Decrypt(byte[] ciphertextAndNonce, byte[] key)
        {
            // Retrieve the nonce and ciphertext.
            byte[] nonce      = new byte[ALGORITHM_NONCE_SIZE];
            byte[] ciphertext = new byte[ciphertextAndNonce.Length - ALGORITHM_NONCE_SIZE];
            Array.Copy(ciphertextAndNonce, 0, nonce, 0, nonce.Length);
            Array.Copy(ciphertextAndNonce, nonce.Length, ciphertext, 0, ciphertext.Length);

            // Create the cipher instance and initialize.
            GcmBlockCipher   cipher           = new GcmBlockCipher(new AesFastEngine());
            KeyParameter     keyParam         = ParameterUtilities.CreateKeyParameter(ALGORITHM_NAME, key);
            ParametersWithIV cipherParameters = new ParametersWithIV(keyParam, nonce);

            cipher.Init(false, cipherParameters);

            // Decrypt and return result.
            byte[] plaintext = new byte[cipher.GetOutputSize(ciphertext.Length)];
            int    length    = cipher.ProcessBytes(ciphertext, 0, ciphertext.Length, plaintext, 0);

            cipher.DoFinal(plaintext, length);

            return(plaintext);
        }
Пример #6
0
        public static byte[] DecryptDES(byte[] cipherData, byte[] derivedKey)
        {
            byte[] output = null;
            try
            {
                KeyParameter    keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey);
                IBufferedCipher cipher   = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING");
                cipher.Init(false, keyparam);
                try
                {
                    output = cipher.DoFinal(cipherData);
                }
                catch (System.Exception ex)
                {
                    throw new CryptoException(ex.Message);
                }
            }
            catch
            {
            }

            return(output);
        }
Пример #7
0
        public void Decode(TextReader vaultFileReader, byte[] password, Stream output)
        {
            var vaultFile      = AnsibleVaultFile.Load(vaultFileReader);
            var cipher         = CipherUtilities.GetCipher("AES/CTR/PKCS7Padding");
            var pbkdf2         = new Rfc2898DeriveBytes(password, vaultFile.Salt, 10000, HashAlgorithmName.SHA256);
            var derived        = pbkdf2.GetBytes(32 + 32 + 16);
            var cipherKeyBytes = derived.AsSpan(0, 32).ToArray();
            var hmacKey        = derived.AsSpan(32, 32).ToArray();
            var iv             = derived.AsSpan(64, 16).ToArray();
            var hmac256        = new HMACSHA256(hmacKey);
            var actualhmac     = hmac256.ComputeHash(vaultFile.EncryptedBytes);

            if (!actualhmac.AsSpan().SequenceEqual(vaultFile.ExpectedHMac))
            {
                throw new InvalidKeyException("HMAC check error: invalid password");
            }
            var cparam = new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", cipherKeyBytes), iv);

            cipher.Init(false, cparam);
            var decrypted = cipher.DoFinal(vaultFile.EncryptedBytes);

            output.Write(decrypted.AsSpan());
        }
Пример #8
0
        public void Encode(byte[] data, byte[] password, byte[] salt, TextWriter output, string label, int width)
        {
            var pbkdf2    = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256);
            var derived   = pbkdf2.GetBytes(32 + 32 + 16);
            var vaultFile = new AnsibleVaultFile();

            vaultFile.Version   = "1.1";
            vaultFile.Algorithm = "AES256";
            vaultFile.Salt      = salt;
            var cipher         = CipherUtilities.GetCipher("AES/CTR/PKCS7Padding");
            var cipherKeyBytes = derived.AsSpan(0, 32).ToArray();
            var hmacKey        = derived.AsSpan(32, 32).ToArray();
            var iv             = derived.AsSpan(64, 16).ToArray();
            var cparam         = new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", cipherKeyBytes), iv);

            cipher.Init(true, cparam);
            var encrypted = cipher.DoFinal(data);
            var hmac256   = new HMACSHA256(hmacKey);

            vaultFile.EncryptedBytes = encrypted;
            vaultFile.ExpectedHMac   = hmac256.ComputeHash(encrypted);
            AnsibleVaultFile.Save(vaultFile, output, label, width);
        }
Пример #9
0
        byte[] DecryptFinal(byte[] cipherData, byte[] derivedKey)
        {
            byte[] output = null;
            try
            {
                var keyparam = ParameterUtilities.CreateKeyParameter("AES", derivedKey);
                var cipher   = CipherUtilities.GetCipher("AES/CBC/PKCS5Padding");
                cipher.Init(false, keyparam);
                try
                {
                    output = cipher.DoFinal(cipherData);
                }
                catch (System.Exception)
                {
                    throw new CryptoException("Invalid Data");
                }
            }
            catch (Exception)
            {
            }

            return(output);
        }
Пример #10
0
        protected void oidTest(
            string[]        oids,
            string[]        names,
            int groupSize)
        {
            byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

            for (int i = 0; i != oids.Length; i++)
            {
                IBufferedCipher    c1 = CipherUtilities.GetCipher(oids[i]);
                IBufferedCipher    c2 = CipherUtilities.GetCipher(names[i]);
                CipherKeyGenerator kg = GeneratorUtilities.GetKeyGenerator(oids[i]);

                KeyParameter k = ParameterUtilities.CreateKeyParameter(oids[i], kg.GenerateKey());

                ICipherParameters cp = k;
                if (names[i].IndexOf("/ECB/") < 0)
                {
                    cp = new ParametersWithIV(cp, new byte[16]);
                }

                c1.Init(true, cp);
                c2.Init(false, cp);

                byte[] result = c2.DoFinal(c1.DoFinal(data));

                if (!AreEqual(data, result))
                {
                    Fail("failed OID test");
                }

                if (k.GetKey().Length != (16 + ((i / groupSize) * 8)))
                {
                    Fail("failed key length test");
                }
            }
        }
Пример #11
0
        /**
         * decrypt the content and return an input stream.
         */
        public override CmsTypedStream GetContentStream(
            ICipherParameters key)
        {
            try
            {
                AlgorithmIdentifier kekAlg       = AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm);
                Asn1Sequence        kekAlgParams = (Asn1Sequence)kekAlg.Parameters;
                byte[]   encryptedKey            = info.EncryptedKey.GetOctets();
                string   kekAlgName = DerObjectIdentifier.GetInstance(kekAlgParams[0]).Id;
                string   cName      = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(kekAlgName);
                IWrapper keyWrapper = WrapperUtilities.GetWrapper(cName);

                byte[] iv = Asn1OctetString.GetInstance(kekAlgParams[1]).GetOctets();

                ICipherParameters parameters = ((CmsPbeKey)key).GetEncoded(kekAlgName);
                parameters = new ParametersWithIV(parameters, iv);

                keyWrapper.Init(false, parameters);

                AlgorithmIdentifier aid = GetActiveAlgID();

                string alg = aid.ObjectID.Id;

                KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
                    alg, keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));

                return(GetContentFromSessionKey(sKey));
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
        }
Пример #12
0
		/**
		* generate an enveloped object that contains an CMS Enveloped Data
		* object using the given provider and the passed in key generator.
		* @throws java.io.IOException
		*/
		private Stream Open(
			Stream				outStr,
			string				macOid,
			CipherKeyGenerator	keyGen)
		{
			// FIXME Will this work for macs?
			byte[] encKeyBytes = keyGen.GenerateKey();
			KeyParameter encKey = ParameterUtilities.CreateKeyParameter(macOid, encKeyBytes);

			Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, encKeyBytes);

			ICipherParameters cipherParameters;
			AlgorithmIdentifier macAlgId = GetAlgorithmIdentifier(
				macOid, encKey, asn1Params, out cipherParameters);

			Asn1EncodableVector recipientInfos = new Asn1EncodableVector();

			foreach (RecipientInfoGenerator rig in recipientInfoGenerators)
			{
				try
				{
					recipientInfos.Add(rig.Generate(encKey, rand));
				}
				catch (InvalidKeyException e)
				{
					throw new CmsException("key inappropriate for algorithm.", e);
				}
				catch (GeneralSecurityException e)
				{
					throw new CmsException("error making encrypted content.", e);
				}
			}

			// FIXME Only passing key at the moment
//			return Open(outStr, macAlgId, cipherParameters, recipientInfos);
			return Open(outStr, macAlgId, encKey, recipientInfos);
		}
        /**
         * decrypt the content and return an input stream.
         */
        public override CmsTypedStream GetContentStream(
            ICipherParameters key)
        {
            try
            {
                byte[]   encryptedKey = info.EncryptedKey.GetOctets();
                IWrapper keyWrapper   = WrapperUtilities.GetWrapper(keyEncAlg.ObjectID.Id);

                keyWrapper.Init(false, key);

                KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
                    GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));

                return(GetContentFromSessionKey(sKey));
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
        }
Пример #14
0
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="data">待解密数据</param>
        /// <param name="key">密钥</param>
        /// <param name="iv">偏移量,ECB模式不用填写!</param>
        /// <param name="algorithm">密文算法</param>
        /// <returns>未加密原文数据</returns>
        public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv, string algorithm)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var cipher = CipherUtilities.GetCipher(algorithm);

            if (iv == null)
            {
                cipher.Init(false, ParameterUtilities.CreateKeyParameter("DES", key));
            }
            else
            {
                cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("DES", key), iv));
            }
            return(cipher.DoFinal(data));
        }
        /**
         * decrypt the content and return it as a byte array.
         */
        public override CmsTypedStream GetContentStream(
            ICipherParameters key)
        {
            byte[] encryptedKey         = _info.EncryptedKey.GetOctets();
            string keyExchangeAlgorithm = GetExchangeEncryptionAlgorithmName(_keyEncAlg.ObjectID);

            try
            {
                IWrapper keyWrapper = WrapperUtilities.GetWrapper(keyExchangeAlgorithm);

                keyWrapper.Init(false, key);

                KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
                    _encAlg.ObjectID, keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));

                return(GetContentFromSessionKey(sKey));
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
//			catch (IllegalBlockSizeException e)
            catch (DataLengthException e)
            {
                throw new CmsException("illegal blocksize in message.", e);
            }
//			catch (BadPaddingException e)
            catch (InvalidCipherTextException e)
            {
                throw new CmsException("bad padding in message.", e);
            }
        }
Пример #16
0
        private EncryptionResponse SealAes(KeyDataResponse keyDataResponse, string secret)
        {
            var plainText = Encoding.UTF8.GetBytes(secret);
            var bytes     = keyDataResponse.Plaintext.ToArray();
            var dataKey   = new byte[32];
            var hmacKey   = new byte[32];

            Buffer.BlockCopy(bytes, 0, dataKey, 0, 32);
            Buffer.BlockCopy(bytes, 32, hmacKey, 0, 32);

            IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");

            cipher.Init(true, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", dataKey), _initializationVector));
            var cipherText = cipher.DoFinal(plainText);

            var hmac       = new HMACSHA256(hmacKey);
            var hmacResult = hmac.ComputeHash(cipherText);

            return(new EncryptionResponse
            {
                CipherText = cipherText,
                Hmac = hmacResult
            });
        }
Пример #17
0
        static byte[] Encrypt(byte[] data, byte[] derivedKey)
        {
            byte[] output = null;
            try
            {
                var keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey);
                var cipher   = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING");
                cipher.Init(true, keyparam);
                try
                {
                    output = cipher.DoFinal(data);
                    return(output);
                }
                catch (System.Exception ex)
                {
                    throw new CryptoException("Invalid Data");
                }
            }
            catch (Exception ex)
            {
            }

            return(output);
        }
Пример #18
0
        public static byte[] AES_GCMDecrypt(byte[] cipherWithNonce, byte[] keyBytes)
        {
            // Gets nonce and ciphertext
            byte[] nonce      = new byte[NONCE_SIZE];
            byte[] ciphertext = new byte[cipherWithNonce.Length - NONCE_SIZE];

            Array.Copy(cipherWithNonce, 0, nonce, 0, nonce.Length);
            Array.Copy(cipherWithNonce, nonce.Length, ciphertext, 0, ciphertext.Length);

            // Specify AES-GCM block cipher
            var blockCipher  = new GcmBlockCipher(new AesEngine());
            var keyParam     = ParameterUtilities.CreateKeyParameter(ENCRYPTION_METHOD, keyBytes);
            var cipherParams = new ParametersWithIV(keyParam, nonce);

            blockCipher.Init(false, cipherParams);

            // Decrypt ciphertext
            byte[] cleartext = new byte[blockCipher.GetOutputSize(ciphertext.Length)];
            int    length    = blockCipher.ProcessBytes(ciphertext, 0, ciphertext.Length, cleartext, 0);

            blockCipher.DoFinal(cleartext, length);

            return(cleartext);
        }
        private static void decrypt(String privateKeyPath,
                                    String encryptedCEK,
                                    String iv,
                                    String encryptedRecordingPath,
                                    String decryptedRecordingPath)
        {
            // 2) Retrieve customer private key corresponding to public_key_sid and use it to decrypt base 64 decoded
            // encrypted_cek via RSAES-OAEP-SHA256-MGF1
            Object pemObject;

            using (var txtreader = File.OpenText(@privateKeyPath))
                pemObject = new PemReader(txtreader).ReadObject();

            var privateKey = (RsaPrivateCrtKeyParameters)((pemObject.GetType() == typeof(AsymmetricCipherKeyPair)) ?
                                                          ((AsymmetricCipherKeyPair)pemObject).Private : pemObject);

            var rsaDecryptEngine = CipherUtilities.GetCipher("RSA/ECB/OAEPWITHSHA256ANDMGF1PADDING");

            rsaDecryptEngine.Init(false, privateKey);
            var encryptedCekArr = Convert.FromBase64String(encryptedCEK);
            var decryptedCekArr = rsaDecryptEngine.DoFinal(encryptedCekArr);

            // 3) Initialize a AES256-GCM SecretKey object with decrypted CEK and base 64 decoded iv
            var               aesDecryptEngine = CipherUtilities.GetCipher("AES/GCM/NOPADDING");
            KeyParameter      keyParameter     = ParameterUtilities.CreateKeyParameter("AES", decryptedCekArr);
            ICipherParameters cipherParameters = new ParametersWithIV(keyParameter, Convert.FromBase64String(iv));

            aesDecryptEngine.Init(false, cipherParameters);

            // 4) Decrypt encrypted recording using the SecretKey
            var          decryptedFile = File.Create(@decryptedRecordingPath);
            CipherStream cipherStream  = new CipherStream(File.OpenRead(@encryptedRecordingPath), aesDecryptEngine, null);

            cipherStream.CopyTo(decryptedFile);
            decryptedFile.Close();
        }
Пример #20
0
        private void doTestAlgorithm(
            string name,
            byte[]  keyBytes,
            byte[]  iv,
            byte[]  plainText,
            byte[]  cipherText)
        {
            KeyParameter key = ParameterUtilities.CreateKeyParameter(name, keyBytes);

            IBufferedCipher inCipher  = CipherUtilities.GetCipher(name);
            IBufferedCipher outCipher = CipherUtilities.GetCipher(name);

            if (iv != null)
            {
                inCipher.Init(true, new ParametersWithIV(key, iv));
                outCipher.Init(false, new ParametersWithIV(key, iv));
            }
            else
            {
                inCipher.Init(true, key);
                outCipher.Init(false, key);
            }

            byte[] enc = inCipher.DoFinal(plainText);
            if (!AreEqual(enc, cipherText))
            {
                Fail(name + ": cipher text doesn't match");
            }

            byte[] dec = outCipher.DoFinal(enc);

            if (!AreEqual(dec, plainText))
            {
                Fail(name + ": plain text doesn't match");
            }
        }
Пример #21
0
        public override void PerformTest()
        {
            for (int i = 0; i != cipherTests1.Length; i += 2)
            {
                doTest(cipherTests1[i], input1, Hex.Decode(cipherTests1[i + 1]));
            }

            for (int i = 0; i != cipherTests2.Length; i += 2)
            {
                doTest(cipherTests2[i], input2, Hex.Decode(cipherTests2[i + 1]));
            }

            //
            // check for less than a block
            //
            try
            {
                IBufferedCipher c = CipherUtilities.GetCipher("AES/CTS/NoPadding");

                c.Init(true, ParameterUtilities.CreateKeyParameter("AES", new byte[16]));

                c.DoFinal(new byte[4]);

                Fail("CTS failed to throw exception");
            }
            catch (Exception e)
            {
//				if (!(e is IllegalBlockSizeException))
                if (!(e is DataLengthException))
                {
                    Fail("CTS exception test - " + e, e);
                }
            }

            doTestExceptions();
        }
        /**
         * decrypt the content and return an input stream.
         */
        public override CmsTypedStream GetContentStream(
//			Key key)
            ICipherParameters key)
        {
            if (!(key is AsymmetricKeyParameter))
            {
                throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
            }

            AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)key;

            if (!privKey.IsPrivate)
            {
                throw new ArgumentException("Expected private key", "key");
            }

            try
            {
                OriginatorPublicKey    origK    = _info.Originator.OriginatorKey;
                PrivateKeyInfo         privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey);
                SubjectPublicKeyInfo   pubInfo  = new SubjectPublicKeyInfo(privInfo.AlgorithmID, origK.PublicKey.GetBytes());
                AsymmetricKeyParameter pubKey   = PublicKeyFactory.CreateKey(pubInfo);

                string wrapAlg = DerObjectIdentifier.GetInstance(
                    Asn1Sequence.GetInstance(_keyEncAlg.Parameters)[0]).Id;

                IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf(
                    _keyEncAlg.ObjectID, wrapAlg);

                agreement.Init(privKey);

                BigInteger wKeyNum = agreement.CalculateAgreement(pubKey);
                // TODO Fix the way bytes are derived from the secret
                byte[]       wKeyBytes = wKeyNum.ToByteArrayUnsigned();
                KeyParameter wKey      = ParameterUtilities.CreateKeyParameter(wrapAlg, wKeyBytes);

                IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg);

                keyCipher.Init(false, wKey);

                AlgorithmIdentifier aid = _encAlg;
                string alg = aid.ObjectID.Id;

                byte[] encryptedKey = _encryptedKey.GetOctets();
                byte[] sKeyBytes    = keyCipher.Unwrap(encryptedKey, 0, encryptedKey.Length);

                KeyParameter sKey = ParameterUtilities.CreateKeyParameter(alg, sKeyBytes);

                return(GetContentFromSessionKey(sKey));
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
            catch (Exception e)
            {
                throw new CmsException("originator key invalid.", e);
            }
        }
        /// <summary>Return the decrypted input stream, using the passed in passphrase.</summary>
        public Stream GetDataStream(char[] passPhrase)
        {
            try
            {
                var keyAlgorithm = _keyData.EncAlgorithm;

                var key = PgpUtilities.MakeKeyFromPassPhrase(
                    keyAlgorithm, _keyData.S2K, passPhrase);


                var secKeyData = _keyData.GetSecKeyData();
                if (secKeyData != null && secKeyData.Length > 0)
                {
                    var keyCipher = CipherUtilities.GetCipher(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding");

                    keyCipher.Init(false,
                                   new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()]));

                    var keyBytes = keyCipher.DoFinal(secKeyData);

                    keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0];

                    key = ParameterUtilities.CreateKeyParameter(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm),
                        keyBytes, 1, keyBytes.Length - 1);
                }


                var c = CreateStreamCipher(keyAlgorithm);

                var iv = new byte[c.GetBlockSize()];

                c.Init(false, new ParametersWithIV(key, iv));

                EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c, null));

                if (EncData is SymmetricEncIntegrityPacket)
                {
                    TruncStream = new TruncatedStream(EncStream);

                    var digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    var digest     = DigestUtilities.GetDigest(digestName);

                    EncStream = new DigestStream(TruncStream, digest, null);
                }

                if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                var v1 = EncStream.ReadByte();
                var v2 = EncStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }


                // Note: the oracle attack on the "quick check" bytes is not deemed
                // a security risk for PBE (see PgpPublicKeyEncryptedData)

                var repeatCheckPassed =
                    iv[iv.Length - 2] == (byte)v1 &&
                    iv[iv.Length - 1] == (byte)v2;

                // Note: some versions of PGP appear to produce 0 for the extra
                // bytes rather than repeating the two previous bytes
                var zeroesCheckPassed = v1 == 0 && v2 == 0;
                if (!repeatCheckPassed && !zeroesCheckPassed)
                {
                    throw new PgpDataValidationException("quick check failed.");
                }


                return(EncStream);
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }
        }
Пример #24
0
        // TODO Make private again and call from PerformTest
        public void doTestExceptions()
        {
            // TODO Put back in
//			SecretKeyFactory skF = null;
//
//			try
//			{
//				skF = SecretKeyFactory.getInstance("DESede");
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}
//
//			KeySpec ks = null;
//			SecretKey secKey = null;
//			byte[] bb = new byte[24];
//
//			try
//			{
//				skF.getKeySpec(null, null);
//
//				Fail("failed exception test - no exception thrown");
//			}
//			catch (InvalidKeySpecException e)
//			{
//				// ignore okay
//			}
//			catch (Exception e)
//			{
//				Fail("failed exception test.", e);
//			}
//			try
//			{
//				ks = (KeySpec)new DESedeKeySpec(bb);
//				skF.getKeySpec(null, ks.getClass());
//
//				Fail("failed exception test - no exception thrown");
//			}
//			catch (InvalidKeySpecException e)
//			{
//				// ignore okay;
//			}
//			catch (Exception e)
//			{
//				Fail("failed exception test.", e);
//			}
//			try
//			{
//				skF.getKeySpec(secKey, null);
//			}
//			catch (InvalidKeySpecException e)
//			{
//				// ignore okay
//			}
//			catch (Exception e)
//			{
//				Fail("failed exception test.", e);
//			}

            try
            {
                CipherKeyGenerator kg = GeneratorUtilities.GetKeyGenerator("DESede");

                try
                {
                    kg.Init(new KeyGenerationParameters(new SecureRandom(), int.MinValue));

                    Fail("failed exception test - no exception thrown");
                }
//				catch (InvalidParameterException)
                catch (ArgumentException)
                {
                    // ignore okay
                }
                catch (Exception e)
                {
                    Fail("failed exception test.", e);
                }
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }

            // TODO Put back in
//			try
//			{
//				skF = SecretKeyFactory.getInstance("DESede");
//
//				try
//				{
//					skF.translateKey(null);
//
//					Fail("failed exception test - no exception thrown");
//				}
//				catch (InvalidKeyException)
//				{
//					// ignore okay
//				}
//				catch (Exception e)
//				{
//					Fail("failed exception test.", e);
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}

//			try
//			{
//				byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134,
//						(byte)137, (byte)138, (byte)140, (byte)143 };
//
////				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");
//				KeyParameter cipherKey = new DesParameters(rawDESKey);
//
//				IBufferedCipher cipher = CipherUtilities.GetCipher("DES/CBC/NoPadding");
//
//				try
//				{
//					// According specification engineInit(int opmode, Key key,
//					// SecureRandom random) throws InvalidKeyException if this
//					// cipher is being
//					// initialized for decryption and requires algorithm parameters
//					// that cannot be determined from the given key
////					cipher.Init(false, cipherKey, (SecureRandom)null);
//					cipher.Init(false, new ParametersWithRandom(cipherKey, new SecureRandom()));
//
//					Fail("failed exception test - no InvalidKeyException thrown");
//				}
//				catch (InvalidKeyException)
//				{
//					// ignore
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}

            try
            {
//				byte[] rawDESKey = { -128, -125, -123, -122, -119, -118 };
                byte[] rawDESKey = { 128, 131, 133, 134, 137, 138 };

//				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");

//				IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/NoPadding");
                try
                {
                    KeyParameter cipherKey = new DesParameters(rawDESKey);

                    // According specification engineInit(int opmode, Key key,
                    // SecureRandom random) throws InvalidKeyException if the given
                    // key is inappropriate for initializing this cipher
//					cipher.Init(true, cipherKey);

//					Fail("failed exception test - no InvalidKeyException thrown");
                    Fail("failed exception test - no ArgumentException thrown");
                }
//				catch (InvalidKeyException)
                catch (ArgumentException)
                {
                    // ignore
                }
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }

//			try
//			{
////				byte[] rawDESKey = { -128, -125, -123, -122, -119, -118, -117, -115, -114 };
//				byte[] rawDESKey = { 128, 131, 133, 134, 137, 138, 139, 141, 142 };
//
////				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");
//				KeyParameter cipherKey = new DesParameters(rawDESKey);
//
//				IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/NoPadding");
//				try
//				{
//					// According specification engineInit(int opmode, Key key,
//					// SecureRandom random) throws InvalidKeyException if the given
//					// key is inappropriate for initializing this cipher
//					cipher.Init(true, cipherKey);
//
//					Fail("failed exception test - no InvalidKeyException thrown");
//				}
//				catch (InvalidKeyException)
//				{
//					// ignore
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}


            try
            {
                byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134,
                                     (byte)137, (byte)138, (byte)140, (byte)143 };

//				SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES");
                KeyParameter cipherKey = new DesParameters(rawDESKey);

                IBufferedCipher ecipher = CipherUtilities.GetCipher("DES/ECB/PKCS5Padding");
                ecipher.Init(true, cipherKey);

                byte[] cipherText = new byte[0];
                try
                {
                    // According specification Method engineUpdate(byte[] input,
                    // int inputOffset, int inputLen, byte[] output, int
                    // outputOffset)
                    // throws ShortBufferException - if the given output buffer is
                    // too
                    // small to hold the result
//					ecipher.update(new byte[20], 0, 20, cipherText);
                    ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0);

//					Fail("failed exception test - no ShortBufferException thrown");
                    Fail("failed exception test - no DataLengthException thrown");
                }
//				catch (ShortBufferException)
                catch (DataLengthException)
                {
                    // ignore
                }
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }

            // TODO Put back in
//			try
//			{
//				KeyGenerator keyGen = KeyGenerator.getInstance("DES");
//
//				keyGen.init((SecureRandom)null);
//
//				// According specification engineGenerateKey() doesn't throw any exceptions.
//
//				SecretKey key = keyGen.generateKey();
//				if (key == null)
//				{
//					Fail("key is null!");
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}
//
//			try
//			{
//				AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES");
//
//				algParams.init(new IvParameterSpec(new byte[8]));
//
//				// According specification engineGetEncoded() returns
//				// the parameters in their primary encoding format. The primary
//				// encoding
//				// format for parameters is ASN.1, if an ASN.1 specification for
//				// this type
//				// of parameters exists.
//				byte[] iv = algParams.getEncoded();
//
//				if (iv.Length!= 10)
//				{
//					Fail("parameters encoding wrong length - "  + iv.Length);
//				}
//			}
//			catch (Exception e)
//			{
//				Fail("unexpected exception.", e);
//			}

            try
            {
                try
                {
//					AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES");

                    byte[] encoding = new byte[10];
                    encoding[0] = 3;
                    encoding[1] = 8;

//					algParams.init(encoding, "ASN.1");
                    ParameterUtilities.GetCipherParameters(
                        "AES",
                        ParameterUtilities.CreateKeyParameter("AES", new byte[16]),
                        Asn1Object.FromByteArray(encoding));

//					Fail("failed exception test - no IOException thrown");
                    Fail("failed exception test - no Exception thrown");
                }
//				catch (IOException)
                catch (ArgumentException)
                {
                    // okay
                }

//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher("DES");
//
//					Key k = new PublicKey()
//					{
//
//						public string getAlgorithm()
//						{
//							return "STUB";
//						}
//
//						public string getFormat()
//						{
//							return null;
//						}
//
//						public byte[] getEncoded()
//						{
//							return null;
//						}
//
//					};
//
//					c.Init(true, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for public key");
//				}
//				catch (InvalidKeyException e)
//				{
//					// okay
//				}
//
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher("DES");
//
//					Key k = new PrivateKey()
//					{
//
//						public string getAlgorithm()
//						{
//							return "STUB";
//						}
//
//						public string getFormat()
//						{
//							return null;
//						}
//
//						public byte[] getEncoded()
//						{
//							return null;
//						}
//
//					};
//
//					c.Init(false, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for private key");
//				}
//				catch (InvalidKeyException e)
//				{
//					// okay
//				}
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }
        }
Пример #25
0
        private void doTest(
            string algorithm,
            byte[]      input,
            byte[]      output)
        {
            KeyParameter       key = null;
            CipherKeyGenerator keyGen;
            SecureRandom       rand;
            IBufferedCipher    inCipher = null, outCipher = null;

            byte[]       iv = null;
            CipherStream cIn, cOut;
            MemoryStream bIn, bOut;

            rand = new FixedSecureRandom();

            string[] parts = algorithm.ToUpper(CultureInfo.InvariantCulture).Split('/');
            string   baseAlgorithm = parts[0];
            string   mode  = parts.Length > 1 ? parts[1] : null;

#if !INCLUDE_IDEA
            if (baseAlgorithm.Equals("IDEA"))
            {
                return;
            }
#endif

            try
            {
                keyGen = GeneratorUtilities.GetKeyGenerator(baseAlgorithm);

                // TODO Add Algorithm property to CipherKeyGenerator?
//				if (!keyGen.getAlgorithm().Equals(baseAlgorithm))
//				{
//					Fail("wrong key generator returned!");
//				}

                // TODO Add new Init method to CipherKeyGenerator?
//				keyGen.Init(rand);
                keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength));

                byte[] keyBytes = keyGen.GenerateKey();

                if (algorithm.StartsWith("RC5"))
                {
                    key = new RC5Parameters(keyBytes, rc5Rounds);
                }
                else
                {
                    key = ParameterUtilities.CreateKeyParameter(baseAlgorithm, keyBytes);
                }

                inCipher  = CipherUtilities.GetCipher(algorithm);
                outCipher = CipherUtilities.GetCipher(algorithm);

                if (!inCipher.AlgorithmName.ToUpper(CultureInfo.InvariantCulture).StartsWith(baseAlgorithm))
                {
                    Fail("wrong cipher returned!");
                }

                ICipherParameters parameters = key;

                int ivLength = GetIVLength(algorithm);

                if (ivLength > 0)
                {
                    if (baseAlgorithm == "RC2")
                    {
                        iv = rc2IV;
                    }
                    else if (baseAlgorithm == "RC5")
                    {
                        iv = rc5IV;
                    }
                    else if (baseAlgorithm == "RC5-64")
                    {
                        iv = rc564IV;
                    }
                    else
                    {
                        // NB: rand always generates same values each test run
                        iv = rand.GenerateSeed(ivLength);
                    }

                    parameters = new ParametersWithIV(key, iv);
                }

                // NB: 'rand' still needed e.g. for some paddings
                parameters = new ParametersWithRandom(parameters, rand);

                outCipher.Init(true, parameters);
            }
            catch (Exception e)
            {
                Fail("" + algorithm + " failed initialisation - " + e.ToString(), e);
            }

            //
            // grab the iv if there is one
            //
            try
            {
                // The Java version set this implicitly, but we set it explicity
                //byte[] iv = outCipher.getIV();

                if (iv != null)
                {
                    // TODO Examine short IV handling for these FIPS-compliant modes in Java build
                    if (mode.StartsWith("CFB") ||
                        mode.StartsWith("GOFB") ||
                        mode.StartsWith("OFB") ||
                        mode.StartsWith("OPENPGPCFB"))
                    {
                        // These modes automatically pad out the IV if it is short
                    }
                    else
                    {
                        try
                        {
                            byte[] nIv = new byte[iv.Length - 1];
                            inCipher.Init(false, new ParametersWithIV(key, nIv));
                            Fail("failed to pick up short IV");
                        }
                        //catch (InvalidAlgorithmParameterException e)
                        catch (ArgumentException)
                        {
                            // ignore - this is what we want...
                        }
                    }

                    //IvParameterSpec spec = new IvParameterSpec(iv);
                    inCipher.Init(false, new ParametersWithIV(key, iv));
                }
                else
                {
                    inCipher.Init(false, key);
                }
            }
            catch (Exception e)
            {
                Fail("" + algorithm + " failed initialisation - " + e.ToString());
            }

            //
            // encryption pass
            //
            bOut = new MemoryStream();
            cOut = new CipherStream(bOut, null, outCipher);

            try
            {
                for (int i = 0; i != input.Length / 2; i++)
                {
                    cOut.WriteByte(input[i]);
                }
                cOut.Write(input, input.Length / 2, input.Length - input.Length / 2);
                cOut.Close();
            }
            catch (IOException e)
            {
                Fail("" + algorithm + " failed encryption - " + e.ToString());
            }

            byte[] bytes = bOut.ToArray();

            if (!AreEqual(bytes, output))
            {
                Fail("" + algorithm + " failed encryption - expected "
                     + Hex.ToHexString(output) + " got "
                     + Hex.ToHexString(bytes));
            }

            //
            // decryption pass
            //
            bIn = new MemoryStream(bytes, false);
            cIn = new CipherStream(bIn, inCipher, null);

            try
            {
                BinaryReader dIn = new BinaryReader(cIn);

                bytes = new byte[input.Length];

                for (int i = 0; i != input.Length / 2; i++)
                {
                    bytes[i] = dIn.ReadByte();
                }

                int    remaining = bytes.Length - input.Length / 2;
                byte[] extra     = dIn.ReadBytes(remaining);
                if (extra.Length < remaining)
                {
                    throw new EndOfStreamException();
                }
                extra.CopyTo(bytes, input.Length / 2);
            }
            catch (Exception e)
            {
                Fail("" + algorithm + " failed decryption - " + e.ToString());
            }

            if (!AreEqual(bytes, input))
            {
                Fail("" + algorithm + " failed decryption - expected "
                     + Hex.ToHexString(input) + " got "
                     + Hex.ToHexString(bytes));
            }
        }
Пример #26
0
        /// <summary>
        /// Generate an enveloped object that contains a CMS Enveloped Data
        /// object using the passed in key generator.
        /// </summary>
        private CmsEnvelopedData Generate(
            CmsProcessable content,
            string encryptionOid,
            CipherKeyGenerator keyGen)
        {
            AlgorithmIdentifier encAlgId = null;
            KeyParameter        encKey;
            Asn1OctetString     encContent;

            try
            {
                byte[] encKeyBytes = keyGen.GenerateKey();
                encKey = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes);

                Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes);

                ICipherParameters cipherParameters;
                encAlgId = GetAlgorithmIdentifier(
                    encryptionOid, encKey, asn1Params, out cipherParameters);

                IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid);
                cipher.Init(true, new ParametersWithRandom(cipherParameters, rand));

                MemoryStream bOut = new MemoryStream();
                CipherStream cOut = new CipherStream(bOut, null, cipher);

                content.Write(cOut);

                Platform.Dispose(cOut);

                encContent = new BerOctetString(bOut.ToArray());
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("exception decoding algorithm parameters.", e);
            }


            Asn1EncodableVector recipientInfos = new Asn1EncodableVector();

            foreach (RecipientInfoGenerator rig in recipientInfoGenerators)
            {
                try
                {
                    recipientInfos.Add(rig.Generate(encKey, rand));
                }
                catch (InvalidKeyException e)
                {
                    throw new CmsException("key inappropriate for algorithm.", e);
                }
                catch (GeneralSecurityException e)
                {
                    throw new CmsException("error making encrypted content.", e);
                }
            }

            EncryptedContentInfo eci = new EncryptedContentInfo(
                CmsObjectIdentifiers.Data,
                encAlgId,
                encContent);

            Asn1Set unprotectedAttrSet = null;

            if (unprotectedAttributeGenerator != null)
            {
                Asn1.Cms.AttributeTable attrTable = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());

                unprotectedAttrSet = new BerSet(attrTable.ToAsn1EncodableVector());
            }

            ContentInfo contentInfo = new ContentInfo(
                CmsObjectIdentifiers.EnvelopedData,
                new EnvelopedData(null, new DerSet(recipientInfos), eci, unprotectedAttrSet));

            return(new CmsEnvelopedData(contentInfo));
        }
Пример #27
0
        private void doRunTest(
            string name,
            int ivLength)
        {
            string lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789";

            string baseName = name;

            if (name.IndexOf('/') >= 0)
            {
                baseName = name.Substring(0, name.IndexOf('/'));
            }

            CipherKeyGenerator kGen = GeneratorUtilities.GetKeyGenerator(baseName);

            IBufferedCipher inCipher  = CipherUtilities.GetCipher(name);
            IBufferedCipher outCipher = CipherUtilities.GetCipher(name);
            KeyParameter    key       = ParameterUtilities.CreateKeyParameter(baseName, kGen.GenerateKey());
            MemoryStream    bIn       = new MemoryStream(Encoding.ASCII.GetBytes(lCode), false);
            MemoryStream    bOut      = new MemoryStream();

            // In the Java build, this IV would be implicitly created and then retrieved with getIV()
            ICipherParameters cipherParams = key;

            if (ivLength > 0)
            {
                cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]);
            }

            inCipher.Init(true, cipherParams);

            // TODO Should we provide GetIV() method on IBufferedCipher?
            //if (inCipher.getIV() != null)
            //{
            //	outCipher.Init(false, new ParametersWithIV(key, inCipher.getIV()));
            //}
            //else
            //{
            //	outCipher.Init(false, key);
            //}
            outCipher.Init(false, cipherParams);

            CipherStream cIn  = new CipherStream(bIn, inCipher, null);
            CipherStream cOut = new CipherStream(bOut, null, outCipher);

            int c;

            while ((c = cIn.ReadByte()) >= 0)
            {
                cOut.WriteByte((byte)c);
            }

            cIn.Close();

            cOut.Flush();
            cOut.Close();

            byte[] bs  = bOut.ToArray();
            string res = Encoding.ASCII.GetString(bs, 0, bs.Length);

            if (!res.Equals(lCode))
            {
                Fail("Failed - decrypted data doesn't match.");
            }
        }
Пример #28
0
        private void doTestException(
            string name,
            int ivLength)
        {
            try
            {
                byte[] key128 =
                {
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143
                };

                byte[] key256 =
                {
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143,
                    (byte)128, (byte)131, (byte)133, (byte)134,
                    (byte)137, (byte)138, (byte)140, (byte)143
                };

                byte[] keyBytes;
                if (name.Equals("HC256"))
                {
                    keyBytes = key256;
                }
                else
                {
                    keyBytes = key128;
                }

                KeyParameter cipherKey = ParameterUtilities.CreateKeyParameter(name, keyBytes);

                ICipherParameters cipherParams = cipherKey;
                if (ivLength > 0)
                {
                    cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]);
                }

                IBufferedCipher ecipher = CipherUtilities.GetCipher(name);
                ecipher.Init(true, cipherParams);

                byte[] cipherText = new byte[0];
                try
                {
                    // According specification Method engineUpdate(byte[] input,
                    // int inputOffset, int inputLen, byte[] output, int
                    // outputOffset)
                    // throws ShortBufferException - if the given output buffer is
                    // too
                    // small to hold the result
                    ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0);

//					Fail("failed exception test - no ShortBufferException thrown");
                    Fail("failed exception test - no DataLengthException thrown");
                }
//				catch (ShortBufferException e)
                catch (DataLengthException)
                {
                    // ignore
                }

                // NB: The lightweight engine doesn't take public/private keys
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher(name);
//
//					//                Key k = new PublicKey()
//					//                {
//					//
//					//                    public string getAlgorithm()
//					//                    {
//					//                        return "STUB";
//					//                    }
//					//
//					//                    public string getFormat()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                    public byte[] getEncoded()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                };
//					AsymmetricKeyParameter k = new AsymmetricKeyParameter(false);
//					c.Init(true, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for public key");
//				}
//				catch (InvalidKeyException)
//				{
//					// okay
//				}
//
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher(name);
//
//					//				Key k = new PrivateKey()
//					//                {
//					//
//					//                    public string getAlgorithm()
//					//                    {
//					//                        return "STUB";
//					//                    }
//					//
//					//                    public string getFormat()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                    public byte[] getEncoded()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                };
//
//					AsymmetricKeyParameter k = new AsymmetricKeyParameter(true);
//					c.Init(false, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for private key");
//				}
//				catch (InvalidKeyException)
//				{
//					// okay
//				}
            }
            catch (Exception e)
            {
                Fail("unexpected exception.", e);
            }
        }
Пример #29
0
        public static void extractAsTar(String backupFilename, String filename, String password)
        {
            try
            {
                Stream inStream = AndroidBackup.getInputStream(backupFilename);

                CipherStream cipherStream = null;
                String       magic        = AndroidBackup.readHeaderLine(inStream); //  1
                if (DEBUG)
                {
                    Console.WriteLine(("Magic: " + magic));
                }

                String versionStr = AndroidBackup.readHeaderLine(inStream);  //  2
                if (DEBUG)
                {
                    Console.WriteLine(("Version: " + versionStr));
                }

                int version = int.Parse(versionStr);
                if (((version < BACKUP_FILE_V1) ||
                     (version > BACKUP_FILE_V4)))
                {
                    throw new ArgumentException("Don\'t know how to process version " + versionStr);
                }

                String compressed = AndroidBackup.readHeaderLine(inStream);  //  3

                bool isCompressed = (int.Parse(compressed) == 1);
                if (DEBUG)
                {
                    Console.WriteLine(("Compressed: " + compressed));
                }

                String encryptionAlg = AndroidBackup.readHeaderLine(inStream); //  4
                if (DEBUG)
                {
                    Console.WriteLine(("Algorithm: " + encryptionAlg));
                }

                bool isEncrypted = false;
                if (encryptionAlg.Equals(ENCRYPTION_ALGORITHM_NAME))
                {
                    isEncrypted = true;


                    //if ((Cipher.getMaxAllowedKeyLength("AES") < MASTER_KEY_SIZE))
                    //{
                    //    Console.WriteLine("WARNING: Maximum allowed key-Length seems smaller than needed. " +
                    //             "Please check that unlimited strength cryptography is available, see README.md for details");
                    //}

                    if (((password == null) ||
                         "".Equals(password)))
                    {
                        Console.WriteLine("This backup is encrypted, please provide the password: "******"Invalid salt Length: " + userSalt.Length));
                    }

                    String ckSaltHex = AndroidBackup.readHeaderLine(inStream); //  6
                    byte[] ckSalt    = AndroidBackup.hexToByteArray(ckSaltHex);

                    int    rounds    = int.Parse(AndroidBackup.readHeaderLine(inStream)); //  7
                    String userIvHex = AndroidBackup.readHeaderLine(inStream);            //  8

                    String masterKeyBlobHex = AndroidBackup.readHeaderLine(inStream);     //  9

                    //  decrypt the master key blob
                    IBufferedCipher c = CipherUtilities.GetCipher(ENCRYPTION_MECHANISM);

                    //  XXX we don't support non-ASCII passwords
                    byte[] userKey = AndroidBackup.buildPasswordKey(password, userSalt, rounds, false);
                    byte[] IV      = AndroidBackup.hexToByteArray(userIvHex);
                    byte[] ivSpec  = IV;

                    c.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES256", userKey), ivSpec));
                    //c.Init(false, new ParametersWithIV(new KeyParameter(userKey), ivSpec));

                    byte[] mkCipher = AndroidBackup.hexToByteArray(masterKeyBlobHex);
                    byte[] mkBlob   = c.DoFinal(mkCipher);
                    //  first, the master key IV
                    int offset = 0;
                    int len    = mkBlob[offset++];
                    IV = Arrays.CopyOfRange(mkBlob, offset, (offset + len));

                    if (DEBUG)
                    {
                        Console.WriteLine(("IV: " + AndroidBackup.toHex(IV)));
                    }

                    offset = (offset + len);
                    //  then the master key itself
                    len = mkBlob[offset++];
                    byte[] mk = Arrays.CopyOfRange(mkBlob, offset, (offset + len));
                    if (DEBUG)
                    {
                        Console.WriteLine(("MK: " + AndroidBackup.toHex(mk)));
                    }

                    offset = (offset + len);
                    //  and finally the master key checksum hash
                    len = mkBlob[offset++];
                    byte[] mkChecksum = Arrays.CopyOfRange(mkBlob, offset, (offset + len));
                    if (DEBUG)
                    {
                        Console.WriteLine(("MK checksum: " + AndroidBackup.toHex(mkChecksum)));
                    }

                    //  now validate the decrypted master key against the checksum
                    //  first try the algorithm matching the archive version
                    bool   useUtf       = (version >= BACKUP_FILE_V2);
                    byte[] calculatedCk = AndroidBackup.makeKeyChecksum(mk, ckSalt, rounds, useUtf);
                    Console.Error.WriteLine("Calculated MK checksum (use UTF-8: {0}): {1}\n", useUtf,
                                            AndroidBackup.toHex(calculatedCk));
                    if (!Arrays.Equals(calculatedCk, mkChecksum))
                    {
                        Console.WriteLine("Checksum does not match.");
                        //  try the reverse
                        calculatedCk = AndroidBackup.makeKeyChecksum(mk, ckSalt, rounds, !useUtf);
                        Console.Error.WriteLine("Calculated MK checksum (use UTF-8: {0}): {1}\n", useUtf,
                                                AndroidBackup.toHex(calculatedCk));
                    }


                    // Even if checksum doesn't match, it works .. No idea why.//
                    //  if (Arrays.Equals(calculatedCk, mkChecksum))
                    {
                        ivSpec = IV;

                        c.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES256", mk), ivSpec));
                        //c.init(Cipher.DECRYPT_MODE, new byte[]Spec(mk, "AES"), ivSpec);
                        //  Only if all of the above worked properly will 'result' be
                        //  assigned
                        cipherStream = new CipherStream(inStream, c, null);
                    }
                }

                if ((isEncrypted &&
                     (cipherStream == null)))
                {
                    throw new Exception("Invalid password or master key checksum.");
                }

                Stream baseStream = isEncrypted ? cipherStream : inStream;
                Stream input      = isCompressed ? new ZInputStream(baseStream) : baseStream;
                Stream output     = null;

                try
                {
                    output = getOutputStream(filename);
                    byte[] buff      = new byte[(10 * 1024)];
                    int    read      = -1;
                    int    totalRead = 0;
                    while ((read = input.Read(buff, 0, buff.Length)) > 0)
                    {
                        output.Write(buff, 0, read);
                        totalRead = (totalRead + read);
                        if ((DEBUG &&
                             ((totalRead % (100 * 1024))
                              == 0)))
                        {
                            Console.Error.WriteLine("{0} bytes written\n", totalRead);
                        }
                    }
                    Console.Error.WriteLine("{0} bytes written to {1}.\n", totalRead, backupFilename);
                }
                finally
                {
                    if (input != null)
                    {
                        input.Close();
                    }

                    if (output != null)
                    {
                        output.Flush();
                        output.Close();
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }
 public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize)
 {
     keySize /= 8;
     byte[] keyBytes = GenerateDerivedKey(keySize);
     return(ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize));
 }