예제 #1
0
        public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
        {
            byte[] keyBytes = contentEncryptionKey.GetKey();
            AlgorithmIdentifier keyEncryptionAlgorithm = info.AlgorithmID;

            IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.Algorithm.Id);

            keyWrapper.Init(true, new ParametersWithRandom(recipientPublicKey, random));
            byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length);

            RecipientIdentifier recipId;

            if (recipientTbsCert != null)
            {
                IssuerAndSerialNumber issuerAndSerial = new IssuerAndSerialNumber(
                    recipientTbsCert.Issuer, recipientTbsCert.SerialNumber.Value);
                recipId = new RecipientIdentifier(issuerAndSerial);
            }
            else
            {
                recipId = new RecipientIdentifier(subjectKeyIdentifier);
            }

            return(new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncryptionAlgorithm,
                                                               new DerOctetString(encryptedKeyBytes))));
        }
        public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
        {
            byte[] keyBytes = contentEncryptionKey.GetKey();

            string   rfc3211WrapperName = Helper.GetRfc3211WrapperName(keyEncryptionKeyOID);
            IWrapper keyWrapper         = Helper.CreateWrapper(rfc3211WrapperName);

            // Note: In Java build, the IV is automatically generated in JCE layer
            int ivLength = Platform.StartsWith(rfc3211WrapperName, "DESEDE") ? 8 : 16;

            byte[] iv = new byte[ivLength];
            random.NextBytes(iv);

            ICipherParameters parameters = new ParametersWithIV(keyEncryptionKey, iv);

            keyWrapper.Init(true, new ParametersWithRandom(parameters, random));
            Asn1OctetString encryptedKey = new DerOctetString(
                keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

            DerSequence seq = new DerSequence(
                new DerObjectIdentifier(keyEncryptionKeyOID),
                new DerOctetString(iv));

            AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(
                PkcsObjectIdentifiers.IdAlgPwriKek, seq);

            return(new RecipientInfo(new PasswordRecipientInfo(
                                         keyDerivationAlgorithm, keyEncryptionAlgorithm, encryptedKey)));
        }
        public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
        {
            byte[] keyBytes = contentEncryptionKey.GetKey();

            IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.Algorithm.Id);

            keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random));
            Asn1OctetString encryptedKey = new DerOctetString(
                keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

            return(new RecipientInfo(new KekRecipientInfo(kekIdentifier, keyEncryptionAlgorithm, encryptedKey)));
        }
        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))));
        }