Пример #1
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);
        }
Пример #2
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();
        }
Пример #3
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");
            }
        }
Пример #4
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);
        }
Пример #5
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
            });
        }
        /**
         * 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 = _encAlg;
                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);
            }
        }
Пример #7
0
        byte[] EncryptFinal(byte[] data, byte[] derivedKey)
        {
            byte[] output = null;
            try
            {
                var keyparam = ParameterUtilities.CreateKeyParameter("AES", derivedKey);
                var cipher   = CipherUtilities.GetCipher("AES/CBC/PKCS5Padding");
                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);
        }
        /**
         * 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);
            }
        }
Пример #9
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));
        }
Пример #10
0
        public static byte[] EncryptDES(byte[] data, byte[] derivedKey)
        {
            byte[] output = null;
            try
            {
                KeyParameter    keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey);
                IBufferedCipher 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(ex.Message);
                }
            }
            catch
            {
            }

            return(output);
        }
        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();
        }
        protected internal virtual AlgorithmIdentifier GetAlgorithmIdentifier(
            string encryptionOid,
            KeyParameter encKey,
            Asn1Encodable asn1Params,
            out ICipherParameters cipherParameters)
        {
            Asn1Object asn1Object;

            if (asn1Params != null)
            {
                asn1Object       = asn1Params.ToAsn1Object();
                cipherParameters = ParameterUtilities.GetCipherParameters(
                    encryptionOid, encKey, asn1Object);
            }
            else
            {
                asn1Object       = DerNull.Instance;
                cipherParameters = encKey;
            }

            return(new AlgorithmIdentifier(
                       new DerObjectIdentifier(encryptionOid),
                       asn1Object));
        }
Пример #13
0
        /**
         * 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.Algorithm.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
        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);
            }
        }
 public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize)
 {
     keySize /= 8;
     byte[] keyBytes = GenerateDerivedKey(keySize);
     return(ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize));
 }
Пример #16
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 RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
        {
            byte[] keyBytes = contentEncryptionKey.GetKey();

            AsymmetricKeyParameter senderPublicKey     = senderKeyPair.Public;
            ICipherParameters      senderPrivateParams = senderKeyPair.Private;


            OriginatorIdentifierOrKey originator;

            try
            {
                originator = new OriginatorIdentifierOrKey(
                    CreateOriginatorPublicKey(senderPublicKey));
            }
            catch (IOException e)
            {
                throw new InvalidKeyException("cannot extract originator public key: " + e);
            }


            Asn1OctetString ukm = null;

            if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
            {
                try
                {
                    IAsymmetricCipherKeyPairGenerator ephemKPG =
                        GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
                    ephemKPG.Init(
                        ((ECPublicKeyParameters)senderPublicKey).CreateKeyGenerationParameters(random));

                    AsymmetricCipherKeyPair ephemKP = ephemKPG.GenerateKeyPair();

                    ukm = new DerOctetString(
                        new MQVuserKeyingMaterial(
                            CreateOriginatorPublicKey(ephemKP.Public), null));

                    senderPrivateParams = new MqvPrivateParameters(
                        (ECPrivateKeyParameters)senderPrivateParams,
                        (ECPrivateKeyParameters)ephemKP.Private,
                        (ECPublicKeyParameters)ephemKP.Public);
                }
                catch (IOException e)
                {
                    throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + e);
                }
                catch (SecurityUtilityException e)
                {
                    throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + e);
                }
            }


            DerSequence paramSeq = new DerSequence(
                keyEncryptionOID,
                DerNull.Instance);
            AlgorithmIdentifier keyEncAlg = new AlgorithmIdentifier(keyAgreementOID, paramSeq);


            Asn1EncodableVector recipientEncryptedKeys = new Asn1EncodableVector();

            foreach (X509Certificate recipientCert in recipientCerts)
            {
                TbsCertificateStructure tbsCert;
                try
                {
                    tbsCert = TbsCertificateStructure.GetInstance(
                        Asn1Object.FromByteArray(recipientCert.GetTbsCertificate()));
                }
                catch (Exception)
                {
                    throw new ArgumentException("can't extract TBS structure from certificate");
                }

                // TODO Should there be a SubjectKeyIdentifier-based alternative?
                IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(
                    tbsCert.Issuer, tbsCert.SerialNumber.Value);
                KeyAgreeRecipientIdentifier karid = new KeyAgreeRecipientIdentifier(issuerSerial);

                ICipherParameters recipientPublicParams = recipientCert.GetPublicKey();
                if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
                {
                    recipientPublicParams = new MqvPublicParameters(
                        (ECPublicKeyParameters)recipientPublicParams,
                        (ECPublicKeyParameters)recipientPublicParams);
                }

                // Use key agreement to choose a wrap key for this recipient
                IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreementWithKdf(
                    keyAgreementOID, keyEncryptionOID.Id);
                keyAgreement.Init(new ParametersWithRandom(senderPrivateParams, random));
                BigInteger agreedValue = keyAgreement.CalculateAgreement(recipientPublicParams);

                int          keyEncryptionKeySize  = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
                byte[]       keyEncryptionKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, keyEncryptionKeySize);
                KeyParameter keyEncryptionKey      = ParameterUtilities.CreateKeyParameter(
                    keyEncryptionOID, keyEncryptionKeyBytes);

                // Wrap the content encryption key with the agreement key
                IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionOID.Id);
                keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random));
                byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length);

                Asn1OctetString encryptedKey = new DerOctetString(encryptedKeyBytes);

                recipientEncryptedKeys.Add(new RecipientEncryptedKey(karid, encryptedKey));
            }

            return(new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg,
                                                               new DerSequence(recipientEncryptedKeys))));
        }
Пример #18
0
        private CmsEnvelopedData Generate(CmsProcessable content, string encryptionOid, CipherKeyGenerator keyGen)
        {
            //IL_0045: Unknown result type (might be due to invalid IL or missing references)
            //IL_004c: Expected O, but got Unknown
            //IL_0096: Expected O, but got Unknown
            AlgorithmIdentifier algorithmIdentifier = null;
            KeyParameter        keyParameter;
            Asn1OctetString     encryptedContent;

            try
            {
                byte[] array = keyGen.GenerateKey();
                keyParameter = ParameterUtilities.CreateKeyParameter(encryptionOid, array);
                Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, array);
                algorithmIdentifier = GetAlgorithmIdentifier(encryptionOid, keyParameter, asn1Params, out var cipherParameters);
                IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid);
                cipher.Init(forEncryption: true, new ParametersWithRandom(cipherParameters, rand));
                MemoryStream val          = new MemoryStream();
                CipherStream cipherStream = new CipherStream((Stream)(object)val, null, cipher);
                content.Write((Stream)(object)cipherStream);
                Platform.Dispose((Stream)(object)cipherStream);
                encryptedContent = new BerOctetString(val.ToArray());
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e2)
            {
                throw new CmsException("key invalid in message.", e2);
            }
            catch (IOException val2)
            {
                IOException e3 = val2;
                throw new CmsException("exception decoding algorithm parameters.", (global::System.Exception)(object) e3);
            }
            Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();

            global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)recipientInfoGenerators).GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    RecipientInfoGenerator recipientInfoGenerator = (RecipientInfoGenerator)enumerator.get_Current();
                    try
                    {
                        asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, rand));
                    }
                    catch (InvalidKeyException e4)
                    {
                        throw new CmsException("key inappropriate for algorithm.", e4);
                    }
                    catch (GeneralSecurityException e5)
                    {
                        throw new CmsException("error making encrypted content.", e5);
                    }
                }
            }
            finally
            {
                global::System.IDisposable disposable = enumerator as global::System.IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
            EncryptedContentInfo encryptedContentInfo = new EncryptedContentInfo(CmsObjectIdentifiers.Data, algorithmIdentifier, encryptedContent);
            Asn1Set unprotectedAttrs = null;

            if (unprotectedAttributeGenerator != null)
            {
                Org.BouncyCastle.Asn1.Cms.AttributeTable attributes = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());
                unprotectedAttrs = new BerSet(attributes.ToAsn1EncodableVector());
            }
            ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.EnvelopedData, new EnvelopedData(null, new DerSet(asn1EncodableVector), encryptedContentInfo, unprotectedAttrs));

            return(new CmsEnvelopedData(contentInfo));
        }
Пример #19
0
        public void DoTest(
            int strength,
            byte[]      keyBytes,
            byte[]      input,
            byte[]      output)
        {
            KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);

            IBufferedCipher inCipher  = CipherUtilities.GetCipher("SM4/ECB/NoPadding");
            IBufferedCipher outCipher = CipherUtilities.GetCipher("SM4/ECB/NoPadding");

            try
            {
                outCipher.Init(true, key);
            }
            catch (Exception e)
            {
                Fail("SM4 failed initialisation - " + e, e);
            }

            try
            {
                inCipher.Init(false, key);
            }
            catch (Exception e)
            {
                Fail("SM4 failed initialisation - " + e, e);
            }

            //
            // encryption pass
            //
            MemoryStream bOut = new MemoryStream();

            CipherStream 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("SM4 failed encryption - " + e, e);
            }

            byte[] bytes = bOut.ToArray();

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

            //
            // decryption pass
            //
            MemoryStream bIn = new MemoryStream(bytes, false);

            CipherStream cIn = new CipherStream(bIn, inCipher, null);

            try
            {
//				DataInputStream dIn = new DataInputStream(cIn);
                BinaryReader dIn = new BinaryReader(cIn);

                bytes = new byte[input.Length];

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

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

            if (!AreEqual(bytes, input))
            {
                Fail("SM4 failed decryption - expected "
                     + Hex.ToHexString(input) + " got "
                     + Hex.ToHexString(bytes));
            }
        }
        /// <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);
            }
        }
Пример #21
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));
            }
        }
Пример #22
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.");
            }
        }
Пример #23
0
        /**
         * generate an enveloped object that contains an CMS Enveloped Data
         * object using the given provider and the passed in key generator.
         */
        private CmsAuthenticatedData Generate(
            CmsProcessable content,
            string macOid,
            CipherKeyGenerator keyGen)
        {
            AlgorithmIdentifier macAlgId;
            KeyParameter        encKey;
            Asn1OctetString     encContent;
            Asn1OctetString     macResult;

            try
            {
                // FIXME Will this work for macs?
                byte[] encKeyBytes = keyGen.GenerateKey();
                encKey = ParameterUtilities.CreateKeyParameter(macOid, encKeyBytes);

                Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, encKeyBytes);

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

                IMac mac = MacUtilities.GetMac(macOid);
                // TODO Confirm no ParametersWithRandom needed
                // FIXME Only passing key at the moment
//	            mac.Init(cipherParameters);
                mac.Init(encKey);

                MemoryStream bOut = new MemoryStream();
                Stream       mOut = new TeeOutputStream(bOut, new MacOutputStream(mac));

                content.Write(mOut);

                mOut.Close();
                bOut.Close();

                encContent = new BerOctetString(bOut.ToArray());

                byte[] macOctets = MacUtilities.DoFinal(mac);
                macResult = new DerOctetString(macOctets);
            }
            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);
                }
            }

            ContentInfo eci = new ContentInfo(CmsObjectIdentifiers.Data, encContent);

            ContentInfo contentInfo = new ContentInfo(
                CmsObjectIdentifiers.AuthenticatedData,
                new AuthenticatedData(null, new DerSet(recipientInfos), macAlgId, null, eci, null, macResult, null));

            return(new CmsAuthenticatedData(contentInfo));
        }
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            byte[] plain = fetchSymmetricKeyData(privKey);

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, plain, 1, plain.Length - 3);

                byte[] iv = new byte[c2.GetBlockSize()];

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

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);

                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest 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.");
                }

                int v1 = encStream.ReadByte();
                int 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 deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool 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
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
Пример #25
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));
        }
        internal CmsTypedStream GetContentFromSessionKey(
            KeyParameter sKey)
        {
            try
            {
                Stream content = data;

                if (encAlg != null)
                {
                    IBufferedCipher cipher = CipherUtilities.GetCipher(encAlg.ObjectID);

                    Asn1Encodable asn1Enc    = encAlg.Parameters;
                    Asn1Object    asn1Params = asn1Enc == null ? null : asn1Enc.ToAsn1Object();

                    ICipherParameters cipherParameters = sKey;

                    if (asn1Params != null && !(asn1Params is Asn1Null))
                    {
                        cipherParameters = ParameterUtilities.GetCipherParameters(
                            encAlg.ObjectID, cipherParameters, asn1Params);
                    }
                    else
                    {
                        string alg = encAlg.ObjectID.Id;
                        if (alg.Equals(CmsEnvelopedDataGenerator.DesEde3Cbc) ||
                            alg.Equals(CmsEnvelopedDataGenerator.IdeaCbc) ||
                            alg.Equals(CmsEnvelopedDataGenerator.Cast5Cbc))
                        {
                            cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]);
                        }
                    }

                    cipher.Init(false, cipherParameters);

                    content = new CipherStream(content, cipher, null);
                }

                // If authenticated, need to wrap in MacStream to calculate MAC
                if (macAlg != null)
                {
                    content = this.macStream = CreateMacStream(macAlg, sKey, content);
                }

                if (authEncAlg != null)
                {
                    // TODO Create AEAD cipher instance to decrypt and calculate tag ( MAC)
                    throw new CmsException("AuthEnveloped data decryption not yet implemented");

//              RFC 5084 ASN.1 Module
//                -- Parameters for AigorithmIdentifier
//
//                CCMParameters ::= SEQUENCE {
//                  aes-nonce         OCTET STRING (SIZE(7..13)),
//                  aes-ICVlen        AES-CCM-ICVlen DEFAULT 12 }
//
//                AES-CCM-ICVlen ::= INTEGER (4 | 6 | 8 | 10 | 12 | 14 | 16)
//
//                GCMParameters ::= SEQUENCE {
//                  aes-nonce        OCTET STRING, -- recommended size is 12 octets
//                  aes-ICVlen       AES-GCM-ICVlen DEFAULT 12 }
//
//                AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16)
                }

                return(new CmsTypedStream(content));
            }
            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("error decoding algorithm parameters.", e);
            }
        }
Пример #27
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);
            }
        }
Пример #28
0
        public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
        {
            //IL_002f: Expected O, but got Unknown
            //IL_00c8: Expected O, but got Unknown
            //IL_0169: Unknown result type (might be due to invalid IL or missing references)
            byte[] key = contentEncryptionKey.GetKey();
            AsymmetricKeyParameter    @public          = senderKeyPair.Public;
            ICipherParameters         cipherParameters = senderKeyPair.Private;
            OriginatorIdentifierOrKey originator;

            try
            {
                originator = new OriginatorIdentifierOrKey(CreateOriginatorPublicKey(@public));
            }
            catch (IOException val)
            {
                IOException val2 = val;
                throw new InvalidKeyException(string.Concat((object)"cannot extract originator public key: ", (object)val2));
            }
            Asn1OctetString ukm = null;

            if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
            {
                try
                {
                    IAsymmetricCipherKeyPairGenerator keyPairGenerator = GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
                    keyPairGenerator.Init(((ECPublicKeyParameters)@public).CreateKeyGenerationParameters(random));
                    AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.GenerateKeyPair();
                    ukm = new DerOctetString(new MQVuserKeyingMaterial(CreateOriginatorPublicKey(asymmetricCipherKeyPair.Public), null));
                    cipherParameters = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters, (ECPrivateKeyParameters)asymmetricCipherKeyPair.Private, (ECPublicKeyParameters)asymmetricCipherKeyPair.Public);
                }
                catch (IOException val3)
                {
                    IOException val4 = val3;
                    throw new InvalidKeyException(string.Concat((object)"cannot extract MQV ephemeral public key: ", (object)val4));
                }
                catch (SecurityUtilityException ex)
                {
                    throw new InvalidKeyException(string.Concat((object)"cannot determine MQV ephemeral key pair parameters from public key: ", (object)ex));
                }
            }
            DerSequence         parameters             = new DerSequence(keyEncryptionOID, DerNull.Instance);
            AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(keyAgreementOID, parameters);
            Asn1EncodableVector asn1EncodableVector    = new Asn1EncodableVector();

            global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)recipientCerts).GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    X509Certificate         x509Certificate = (X509Certificate)enumerator.get_Current();
                    TbsCertificateStructure instance;
                    try
                    {
                        instance = TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(x509Certificate.GetTbsCertificate()));
                    }
                    catch (global::System.Exception)
                    {
                        throw new ArgumentException("can't extract TBS structure from certificate");
                    }
                    IssuerAndSerialNumber       issuerSerial      = new IssuerAndSerialNumber(instance.Issuer, instance.SerialNumber.Value);
                    KeyAgreeRecipientIdentifier id                = new KeyAgreeRecipientIdentifier(issuerSerial);
                    ICipherParameters           cipherParameters2 = x509Certificate.GetPublicKey();
                    if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
                    {
                        cipherParameters2 = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters2, (ECPublicKeyParameters)cipherParameters2);
                    }
                    IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(keyAgreementOID, keyEncryptionOID.Id);
                    basicAgreementWithKdf.Init(new ParametersWithRandom(cipherParameters, random));
                    BigInteger   s           = basicAgreementWithKdf.CalculateAgreement(cipherParameters2);
                    int          qLength     = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
                    byte[]       keyBytes    = X9IntegerConverter.IntegerToBytes(s, qLength);
                    KeyParameter parameters2 = ParameterUtilities.CreateKeyParameter(keyEncryptionOID, keyBytes);
                    IWrapper     wrapper     = Helper.CreateWrapper(keyEncryptionOID.Id);
                    wrapper.Init(forWrapping: true, new ParametersWithRandom(parameters2, random));
                    byte[]          str          = wrapper.Wrap(key, 0, key.Length);
                    Asn1OctetString encryptedKey = new DerOctetString(str);
                    asn1EncodableVector.Add(new RecipientEncryptedKey(id, encryptedKey));
                }
            }
            finally
            {
                global::System.IDisposable disposable = enumerator as global::System.IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
            return(new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncryptionAlgorithm, new DerSequence(asn1EncodableVector))));
        }
        /**
         * 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);
            }
        }
Пример #30
0
        public static KeyParameter generateKeyFromBytes(byte[] key)
        {
            KeyParameter param = ParameterUtilities.CreateKeyParameter("Serpent", key);

            return(param);
        }