/// <summary>
        /// Authorize a member identified by memberCertificate to decrypt data under
        /// the policy.
        /// </summary>
        ///
        /// <param name="memberCertificate"></param>
        /// <returns>The published KDK Data packet.</returns>
        public Data addMember(CertificateV2 memberCertificate)
        {
            Name kdkName = new Name(nacKey_.getIdentityName());

            kdkName.append(net.named_data.jndn.encrypt.EncryptorV2.NAME_COMPONENT_KDK)
            .append(nacKey_.getName().get(-1))
            // key-id
            .append(net.named_data.jndn.encrypt.EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY)
            .append(memberCertificate.getKeyName());

            int secretLength = 32;

            byte[] secret = new byte[secretLength];
            net.named_data.jndn.util.Common.getRandom().nextBytes(secret);
            // To be compatible with OpenSSL which uses a null-terminated string,
            // replace each 0 with 1. And to be compatible with the Java security
            // library which interprets the secret as a char array converted to UTF8,
            // limit each byte to the ASCII range 1 to 127.
            for (int i = 0; i < secretLength; ++i)
            {
                if (secret[i] == 0)
                {
                    secret[i] = 1;
                }

                secret[i] &= 0x7f;
            }

            SafeBag kdkSafeBag = keyChain_.exportSafeBag(
                nacKey_.getDefaultCertificate(), ILOG.J2CsMapping.NIO.ByteBuffer.wrap(secret));

            PublicKey memberKey = new PublicKey(memberCertificate.getPublicKey());

            EncryptedContent encryptedContent = new EncryptedContent();

            encryptedContent.setPayload(kdkSafeBag.wireEncode());
            encryptedContent.setPayloadKey(memberKey.encrypt(secret,
                                                             net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep));

            Data kdkData = new Data(kdkName);

            kdkData.setContent(encryptedContent.wireEncodeV2());
            // FreshnessPeriod can serve as a soft access control for revoking access.
            kdkData.getMetaInfo().setFreshnessPeriod(
                DEFAULT_KDK_FRESHNESS_PERIOD_MS);
            keyChain_.sign(kdkData, new SigningInfo(identity_));

            storage_.insert(kdkData);

            return(kdkData);
        }