예제 #1
0
        /**
         * instead of a password, it's also possible to decrypt via certificate.
         * Warning: this code is experimental and hasn't been validated
         *
         * @see <a href="http://social.msdn.microsoft.com/Forums/en-US/cc9092bb-0c82-4b5b-ae21-abf643bdb37c/agile-encryption-with-certificates">Agile encryption with certificates</a>
         *
         * @param keyPair
         * @param x509
         * @return true, when the data can be successfully decrypted with the given private key
         * @throws GeneralSecurityException
         */
        public bool VerifyPassword(KeyPair keyPair, X509Certificate x509)
        {
            AgileEncryptionVerifier ver        = (AgileEncryptionVerifier)builder.GetVerifier();
            AgileEncryptionHeader   header     = (AgileEncryptionHeader)builder.GetHeader();
            HashAlgorithm           hashAlgo   = header.HashAlgorithm;
            CipherAlgorithm         cipherAlgo = header.CipherAlgorithm;
            int blockSize = header.BlockSize;

            AgileCertificateEntry ace = null;

            foreach (AgileCertificateEntry aceEntry in ver.GetCertificates())
            {
                if (x509.Equals(aceEntry.x509))
                {
                    ace = aceEntry;
                    break;
                }
            }
            if (ace == null)
            {
                return(false);
            }

            Cipher cipher = Cipher.GetInstance("RSA");

            cipher.Init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
            byte[]        keyspec   = cipher.DoFinal(ace.encryptedKey);
            SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.CipherAlgorithm.jceId);

            Mac x509Hmac = CryptoFunctions.GetMac(hashAlgo);

            x509Hmac.Init(secretKey);
            byte[] certVerifier = x509Hmac.DoFinal(ace.x509.GetEncoded());

            byte[] vec = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityKeyBlock, blockSize);
            cipher = GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE);
            byte[] hmacKey = cipher.DoFinal(header.GetEncryptedHmacKey());
            hmacKey = GetBlock0(hmacKey, hashAlgo.hashSize);

            vec    = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityValueBlock, blockSize);
            cipher = GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE);
            byte[] hmacValue = cipher.DoFinal(header.GetEncryptedHmacValue());
            hmacValue = GetBlock0(hmacValue, hashAlgo.hashSize);


            if (Arrays.Equals(ace.certVerifier, certVerifier))
            {
                SetSecretKey(secretKey);
                SetIntegrityHmacKey(hmacKey);
                SetIntegrityHmacValue(hmacValue);
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #2
0
파일: AmazonS3.cs 프로젝트: shoff/ngit
        /// <exception cref="System.IO.IOException"></exception>
        private void Authorize(HttpURLConnection c)
        {
            IDictionary <string, IList <string> > reqHdr = c.GetRequestProperties();
            SortedDictionary <string, string>     sigHdr = new SortedDictionary <string, string>();

            foreach (KeyValuePair <string, IList <string> > entry in reqHdr.EntrySet())
            {
                string hdr = entry.Key;
                if (IsSignedHeader(hdr))
                {
                    sigHdr.Put(StringUtils.ToLowerCase(hdr), ToCleanString(entry.Value));
                }
            }
            StringBuilder s = new StringBuilder();

            s.Append(c.GetRequestMethod());
            s.Append('\n');
            s.Append(Remove(sigHdr, "content-md5"));
            s.Append('\n');
            s.Append(Remove(sigHdr, "content-type"));
            s.Append('\n');
            s.Append(Remove(sigHdr, "date"));
            s.Append('\n');
            foreach (KeyValuePair <string, string> e in sigHdr.EntrySet())
            {
                s.Append(e.Key);
                s.Append(':');
                s.Append(e.Value);
                s.Append('\n');
            }
            string host = c.GetURL().GetHost();

            s.Append('/');
            s.Append(Sharpen.Runtime.Substring(host, 0, host.Length - DOMAIN.Length - 1));
            s.Append(c.GetURL().AbsolutePath);
            string sec;

            try
            {
                Mac m = Mac.GetInstance(HMAC);
                m.Init(privateKey);
                sec = Base64.EncodeBytes(m.DoFinal(Sharpen.Runtime.GetBytesForString(s.ToString()
                                                                                     , "UTF-8")));
            }
            catch (NoSuchAlgorithmException e_1)
            {
                throw new IOException(MessageFormat.Format(JGitText.Get().noHMACsupport, HMAC, e_1
                                                           .Message));
            }
            catch (InvalidKeyException e_1)
            {
                throw new IOException(MessageFormat.Format(JGitText.Get().invalidKey, e_1.Message
                                                           ));
            }
            c.SetRequestProperty("Authorization", "AWS " + publicKey + ":" + sec);
        }
 public virtual void DoFinal(byte[] buf, int offset)
 {
     try
     {
         mac.DoFinal(buf, offset);
     }
     catch (ShortBufferException)
     {
     }
 }
예제 #4
0
 public virtual void DoFinal(byte[] buf, int offset)
 {
     try
     {
         mac.DoFinal(_buf16, 0);
     }
     catch (ShortBufferException)
     {
     }
     System.Array.Copy(_buf16, 0, buf, offset, 12);
 }
예제 #5
0
        /// <summary>
        /// Compute HMAC of the identifier using the secret key and return the
        /// output as password
        /// </summary>
        /// <param name="identifier">the bytes of the identifier</param>
        /// <param name="key">the secret key</param>
        /// <returns>the bytes of the generated password</returns>
        protected internal static byte[] CreatePassword(byte[] identifier, SecretKey key)
        {
            Mac mac = threadLocalMac.Get();

            try
            {
                mac.Init(key);
            }
            catch (InvalidKeyException ike)
            {
                throw new ArgumentException("Invalid key to HMAC computation", ike);
            }
            return(mac.DoFinal(identifier));
        }
예제 #6
0
        protected override byte[] DecryptBlock(
            byte[] inEnc,
            int inOff,
            int inLen)
        {
            // Ensure that the length of the input is greater than the MAC in bytes
            if (inLen < (V.Length + Mac.GetMacSize()))
            {
                throw new InvalidCipherTextException("Length of input must be greater than the MAC and V combined");
            }

            // note order is important: set up keys, do simple encryption, check mac, do final encryption.
            if (Cipher == null)
            {
                // Streaming mode.
                throw new ArgumentNullException(string.Format("{0}", "Cipher Cannot be Null in This Mode."));
            }
            // Block cipher mode.

            SetupBlockCipherAndMacKeyBytes(out byte[] k1, out byte[] k2);

            ICipherParameters cp = new KeyParameter(k1);

            // If IV provide use it to initialize the cipher
            if (Iv != null)
            {
                cp = new ParametersWithIV(cp, Iv);
            }

            Cipher.Init(false, cp);

            // Verify the MAC.
            byte[] t1 = new byte[Mac.GetMacSize()];
            Array.Copy(inEnc, V.Length, t1, 0, t1.Length);

            byte[] t2 = new byte[t1.Length];
            Mac.Init(new KeyParameter(k2));
            Mac.BlockUpdate(inEnc, inOff + V.Length + t2.Length, inLen - V.Length - t2.Length);

            Mac.DoFinal(t2, 0);

            if (!Arrays.ConstantTimeAreEqual(t1, t2))
            {
                throw new InvalidCipherTextException("invalid MAC");
            }

            return(Cipher.DoFinal(inEnc, inOff + V.Length + Mac.GetMacSize(),
                                  inLen - V.Length - t2.Length));
        }
        /**
         * Example code from http://msdn.microsoft.com/library/azure/dn495627.aspx to
         * construct a SaS token from the access key to authenticate a request.
         *
         * @param uri The unencoded resource URI string for this operation. The resource
         *            URI is the full URI of the Service Bus resource to which access is
         *            claimed. For example,
         *            "http://<namespace>.servicebus.windows.net/<hubName>"
         */
        private static String GenerateSasToken(String uri)
        {
            String targetUri;
            String token = null;

            try
            {
                targetUri = new String(URLEncoder
                                       .Encode(uri.ToString().ToLower(), "UTF-8")
                                       .ToLower());

                long expiresOnDate = JavaSystem.CurrentTimeMillis();
                int  expiresInMins = 60; // 1 hour
                expiresOnDate += expiresInMins * 60 * 1000;
                long   expires = expiresOnDate / 1000;
                String toSign  = new String(targetUri + "\n" + expires);

                // Get an hmac_sha1 key from the raw key bytes
                byte[]        keyBytes   = HubSasKeyValue.GetBytes("UTF-8");
                SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256");

                // Get an hmac_sha1 Mac instance and initialize with the signing key
                Mac mac = Mac.GetInstance("HmacSHA256");
                mac.Init(signingKey);

                // Compute the hmac on input data bytes
                byte[] rawHmac = mac.DoFinal(toSign.GetBytes("UTF-8"));

                // Using android.util.Base64 for Android Studio instead of
                // Apache commons codec
                String signature = new String(URLEncoder.Encode(
                                                  Base64.EncodeToString(rawHmac, Base64Flags.NoWrap).ToString(), "UTF-8"));

                // Construct authorization string
                token = new String("SharedAccessSignature sr=" + targetUri + "&sig="
                                   + signature + "&se=" + expires + "&skn=" + HubSasKeyName);
            }
            catch (Exception e)
            {
                MainActivity.CurrentActivity.ToastNotify("Exception Generating SaS : " + e.Message.ToString());
                //if (isVisible)
                //{
                //    ToastNotify("Exception Generating SaS : " + e.getMessage().toString());
                //}
            }
            return(token);
        }
예제 #8
0
        /**
         * Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message),
         * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key.
         * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be
         * used as the message.
         *
         * Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes:
         * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33.
         **/
        protected void UpdateIntegrityHMAC(FileInfo tmpFile, int oleStreamSize)
        {
            // as the integrity hmac needs to contain the StreamSize,
            // it's not possible to calculate it on-the-fly while buffering
            // TODO: add stream size parameter to GetDataStream()
            AgileEncryptionVerifier ver      = builder.GetVerifier();
            HashAlgorithm           hashAlgo = ver.HashAlgorithm;
            Mac integrityMD = CryptoFunctions.GetMac(hashAlgo);

            integrityMD.Init(new SecretKeySpec(integritySalt, hashAlgo.jceHmacId));

            byte[] buf = new byte[1024];
            LittleEndian.PutLong(buf, 0, oleStreamSize);
            integrityMD.Update(buf, 0, LittleEndian.LONG_SIZE);

            FileStream fis = tmpFile.Create();

            try {
                int readBytes;
                while ((readBytes = fis.Read(buf, 0, buf.Length)) > 0)
                {
                    integrityMD.Update(buf, 0, readBytes);
                }
            } finally {
                fis.Close();
            }

            byte[] hmacValue = integrityMD.DoFinal();

            AgileEncryptionHeader header = builder.GetHeader();
            int blockSize = header.BlockSize;

            byte[] iv     = CryptoFunctions.GenerateIv(header.HashAlgorithm, header.KeySalt, AgileDecryptor.kIntegrityValueBlock, blockSize);
            Cipher cipher = CryptoFunctions.GetCipher(GetSecretKey(), header.CipherAlgorithm, header.ChainingMode, iv, Cipher.ENCRYPT_MODE);

            byte[] hmacValueFilled    = GetBlock0(hmacValue, AgileDecryptor.GetNextBlockSize(hmacValue.Length, blockSize));
            byte[] encryptedHmacValue = cipher.DoFinal(hmacValueFilled);

            header.SetEncryptedHmacValue(encryptedHmacValue);
        }
예제 #9
0
        private byte[] DecryptBlock(
            byte[] inEnc,
            int inOff,
            int inLen,
            byte[] macData)
        {
            byte[] M = null, K = null, K1 = null, K2 = null;
            int    len;

            // Ensure that the length of the input is greater than the MAC in bytes
            if (inLen <= _iesParameters.MacKeySize / 8)
            {
                throw new InvalidCipherTextException("Length of input must be greater than the MAC");
            }

            if (Cipher == null)
            {
                // Streaming mode.
                K1 = new byte[inLen - V.Length - Mac.GetMacSize()];
                K2 = new byte[_iesParameters.MacKeySize / 8];
                K  = new byte[K1.Length + K2.Length];

                _kdf.GenerateBytes(K, 0, K.Length);

//            if (V.Length != 0)
//            {
//                Array.Copy(K, 0, K2, 0, K2.Length);
//                Array.Copy(K, K2.Length, K1, 0, K1.Length);
//            }
//            else
                {
                    Array.Copy(K, 0, K1, 0, K1.Length);
                    Array.Copy(K, K1.Length, K2, 0, K2.Length);
                }

                M = new byte[K1.Length];

                for (int i = 0; i != K1.Length; i++)
                {
                    M[i] = (byte)(inEnc[inOff + V.Length + i] ^ K1[i]);
                }

                len = K1.Length;
            }
            else
            {
                // Block cipher mode.
                K1 = new byte[((IesWithCipherParameters)_iesParameters).CipherKeySize / 8];
                K2 = new byte[_iesParameters.MacKeySize / 8];
                K  = new byte[K1.Length + K2.Length];

                _kdf.GenerateBytes(K, 0, K.Length);
                Array.Copy(K, 0, K1, 0, K1.Length);
                Array.Copy(K, K1.Length, K2, 0, K2.Length);

                // If IV provide use it to initialize the cipher
                if (_iv != null)
                {
                    Cipher.Init(false, new ParametersWithIV(new KeyParameter(K1), _iv));
                }
                else
                {
                    Cipher.Init(false, new KeyParameter(K1));
                }

                M    = new byte[Cipher.GetOutputSize(inLen - V.Length - Mac.GetMacSize())];
                len  = Cipher.ProcessBytes(inEnc, inOff + V.Length, inLen - V.Length - Mac.GetMacSize(), M, 0);
                len += Cipher.DoFinal(M, len);
            }


            // Convert the length of the encoding vector into a byte array.
            byte[] p2 = _iesParameters.GetEncodingV();

            // Verify the MAC.
            int end = inOff + inLen;

            byte[] t1 = Arrays.CopyOfRange(inEnc, end - Mac.GetMacSize(), end);

            byte[] t2 = new byte[t1.Length];
            byte[] k2A;
            if (HashK2)
            {
                k2A = new byte[_hash.GetDigestSize()];
                _hash.Reset();
                _hash.BlockUpdate(K2, 0, K2.Length);
                _hash.DoFinal(k2A, 0);
            }
            else
            {
                k2A = K2;
            }
            Mac.Init(new KeyParameter(k2A));
            Mac.BlockUpdate(_iv, 0, _iv.Length);
            Mac.BlockUpdate(inEnc, inOff + V.Length, inLen - V.Length - t2.Length);

            if (p2 != null)
            {
                Mac.BlockUpdate(p2, 0, p2.Length);
            }

            if (V.Length != 0 && p2 != null)
            {
//            byte[] L2 = new byte[4];
//            Pack.intToBigEndian(P2.Length * 8, L2, 0);
                byte[] L2 = (p2.Length * 8).ToBigEndianByteArray();
                Debug.Assert(L2.Length == 4, "expected to be 4 bytes long");

                Mac.BlockUpdate(L2, 0, L2.Length);
            }

            if (macData != null)
            {
                Mac.BlockUpdate(macData, 0, macData.Length);
            }

            Mac.DoFinal(t2, 0);

            if (!Arrays.ConstantTimeAreEqual(t1, t2))
            {
                throw new InvalidCipherTextException("Invalid MAC.");
            }

            // Output the message.
            return(Arrays.CopyOfRange(M, 0, len));
        }
예제 #10
0
        private byte[] EncryptBlock(
            byte[] input,
            int inOff,
            int inLen,
            byte[] macData)
        {
            byte[] c, k, k1, k2;
            int    len;

            if (Cipher == null)
            {
                // Streaming mode.
                k1 = new byte[inLen];
                k2 = new byte[_iesParameters.MacKeySize / 8];
                k  = new byte[k1.Length + k2.Length];

                _kdf.GenerateBytes(k, 0, k.Length);

//            if (V.Length != 0)
//            {
//                Array.Copy(K, 0, K2, 0, K2.Length);
//                Array.Copy(K, K2.Length, K1, 0, K1.Length);
//            }
//            else
                {
                    Array.Copy(k, 0, k1, 0, k1.Length);
                    Array.Copy(k, inLen, k2, 0, k2.Length);
                }

                c = new byte[inLen];

                for (int i = 0; i != inLen; i++)
                {
                    c[i] = (byte)(input[inOff + i] ^ k1[i]);
                }
                len = inLen;
            }
            else
            {
                // Block cipher mode.
                k1 = new byte[((IesWithCipherParameters)_iesParameters).CipherKeySize / 8];
                k2 = new byte[_iesParameters.MacKeySize / 8];
                k  = new byte[k1.Length + k2.Length];

                _kdf.GenerateBytes(k, 0, k.Length);
                Array.Copy(k, 0, k1, 0, k1.Length);
                Array.Copy(k, k1.Length, k2, 0, k2.Length);

                // If iv provided use it to initialise the cipher
                if (_iv != null)
                {
                    Cipher.Init(true, new ParametersWithIV(new KeyParameter(k1), _iv));
                }
                else
                {
                    Cipher.Init(true, new KeyParameter(k1));
                }

                c    = new byte[Cipher.GetOutputSize(inLen)];
                len  = Cipher.ProcessBytes(input, inOff, inLen, c, 0);
                len += Cipher.DoFinal(c, len);
            }


            // Convert the length of the encoding vector into a byte array.
            byte[] p2 = _iesParameters.GetEncodingV();

            // Apply the MAC.
            byte[] T = new byte[Mac.GetMacSize()];

            byte[] k2A;
            if (HashK2)
            {
                k2A = new byte[_hash.GetDigestSize()];
                _hash.Reset();
                _hash.BlockUpdate(k2, 0, k2.Length);
                _hash.DoFinal(k2A, 0);
            }
            else
            {
                k2A = k2;
            }
            Mac.Init(new KeyParameter(k2A));
            Mac.BlockUpdate(_iv, 0, _iv.Length);
            Mac.BlockUpdate(c, 0, c.Length);
            if (p2 != null)
            {
                Mac.BlockUpdate(p2, 0, p2.Length);
            }
            if (V.Length != 0 && p2 != null)
            {
//            byte[] L2 = new byte[4];
//            Pack.intToBigEndian(P2.Length * 8, L2, 0);
                byte[] L2 = (p2.Length * 8).ToBigEndianByteArray();
                Debug.Assert(L2.Length == 4, "expected to be 4 bytes long");
                Mac.BlockUpdate(L2, 0, L2.Length);
            }

            if (macData != null)
            {
                Mac.BlockUpdate(macData, 0, macData.Length);
            }

            Mac.DoFinal(T, 0);

            // Output the triple (V,C,T).
            byte[] Output = new byte[V.Length + len + T.Length];
            Array.Copy(V, 0, Output, 0, V.Length);
            Array.Copy(c, 0, Output, V.Length, len);
            Array.Copy(T, 0, Output, V.Length + len, T.Length);
            return(Output);
        }
예제 #11
0
        public override void ConfirmPassword(String password, byte[] keySpec, byte[] keySalt, byte[] verifier, byte[] verifierSalt, byte[] integritySalt)
        {
            AgileEncryptionVerifier ver = builder.GetVerifier();

            ver.Salt = (/*setter*/ verifierSalt);
            AgileEncryptionHeader header = builder.GetHeader();

            header.KeySalt = (/*setter*/ keySalt);
            HashAlgorithm hashAlgo = ver.HashAlgorithm;

            int blockSize = header.BlockSize;

            pwHash = HashPassword(password, hashAlgo, verifierSalt, ver.SpinCount);

            /**
             * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps:
             * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize
             *    attribute.
             * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, and 0x79.
             * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
             *    attribute as an Initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
             *    integral multiple of blockSize bytes, pad the array with 0x00 to the next integral multiple of
             *    blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] encryptedVerifier = AgileDecryptor.hashInput(builder, pwHash, AgileDecryptor.kVerifierInputBlock, verifier, Cipher.ENCRYPT_MODE);
            ver.EncryptedVerifier = (/*setter*/ encryptedVerifier);


            /**
             * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps:
             * 1. Obtain the hash value of the random array of bytes generated in step 1 of the steps for
             *    encryptedVerifierHashInput.
             * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, and 0x4e.
             * 3. Encrypt the hash value obtained in step 1 by using the binary form of the saltValue attribute as
             *    an Initialization vector as specified in section 2.3.4.12. If hashSize is not an integral multiple of
             *    blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            MessageDigest hashMD = GetMessageDigest(hashAlgo);

            byte[] hashedVerifier        = hashMD.Digest(verifier);
            byte[] encryptedVerifierHash = AgileDecryptor.hashInput(builder, pwHash, AgileDecryptor.kHashedVerifierBlock, hashedVerifier, Cipher.ENCRYPT_MODE);
            ver.EncryptedVerifierHash = (/*setter*/ encryptedVerifierHash);

            /**
             * encryptedKeyValue: This attribute MUST be generated by using the following steps:
             * 1. Generate a random array of bytes that is the same size as specified by the
             *    Encryptor.KeyData.keyBits attribute of the parent element.
             * 2. Generate an encryption key as specified in section 2.3.4.11, using the user-supplied password,
             *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
             *    consisting of the following bytes: 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, and 0xd6.
             * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
             *    attribute as an Initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
             *    integral multiple of blockSize bytes, pad the array with 0x00 to an integral multiple of
             *    blockSize bytes.
             * 4. Use base64 to encode the result of step 3.
             */
            byte[] encryptedKey = AgileDecryptor.hashInput(builder, pwHash, AgileDecryptor.kCryptoKeyBlock, keySpec, Cipher.ENCRYPT_MODE);
            ver.EncryptedKey = (/*setter*/ encryptedKey);

            ISecretKey secretKey = new SecretKeySpec(keySpec, ver.CipherAlgorithm.jceId);

            SetSecretKey(secretKey);

            /*
             * 2.3.4.14 DataIntegrity Generation (Agile Encryption)
             *
             * The DataIntegrity element Contained within an Encryption element MUST be generated by using
             * the following steps:
             * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor
             *    Contained within the KeyEncryptors sequence. Use this key for encryption operations in the
             *    remaining steps of this section.
             * 2. Generate a random array of bytes, known as Salt, of the same length as the value of the
             *    KeyData.HashSize attribute.
             * 3. Encrypt the random array of bytes generated in step 2 by using the binary form of the
             *    KeyData.saltValue attribute and a blockKey byte array consisting of the following bytes:
             *    0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, and 0xf6 used to form an Initialization vector as
             *    specified in section 2.3.4.12. If the array of bytes is not an integral multiple of blockSize
             *    bytes, pad the array with 0x00 to the next integral multiple of blockSize bytes.
             * 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3.
             * 5. Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message),
             *    which the DataIntegrity element will verify by using the Salt generated in step 2 as the key.
             *    Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be
             *    used as the message.
             * 6. Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes:
             *    0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33.
             * 7.  Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6.
             */
            this.integritySalt = integritySalt;

            try {
                byte[] vec              = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, AgileDecryptor.kIntegrityKeyBlock, header.BlockSize);
                Cipher cipher           = GetCipher(secretKey, ver.CipherAlgorithm, ver.ChainingMode, vec, Cipher.ENCRYPT_MODE);
                byte[] FilledSalt       = GetBlock0(integritySalt, AgileDecryptor.GetNextBlockSize(integritySalt.Length, blockSize));
                byte[] encryptedHmacKey = cipher.DoFinal(FilledSalt);
                header.SetEncryptedHmacKey(encryptedHmacKey);

                cipher = Cipher.GetInstance("RSA");
                foreach (AgileCertificateEntry ace in ver.GetCertificates())
                {
                    cipher.Init(Cipher.ENCRYPT_MODE, ace.x509.GetPublicKey());
                    ace.encryptedKey = cipher.DoFinal(GetSecretKey().GetEncoded());
                    Mac x509Hmac = CryptoFunctions.GetMac(hashAlgo);
                    x509Hmac.Init(GetSecretKey());
                    ace.certVerifier = x509Hmac.DoFinal(ace.x509.GetEncoded());
                }
            } catch (Exception e) {
                throw new EncryptedDocumentException(e);
            }
        }
예제 #12
0
        protected override unsafe byte[] EncryptBlock(
            byte[] @in,
            int inOff,
            int inLen)
        {
            if (Cipher == null)
            {
                // Streaming mode.
                throw new ArgumentNullException(string.Format("{0}", "Cipher Cannot be Null in This Mode."));
            }
            // Block cipher mode.

            SetupBlockCipherAndMacKeyBytes(out byte[] k1, out byte[] k2);


            // If iv provided use it to initialise the cipher
            if (Iv != null)
            {
                Cipher.Init(true, new ParametersWithIV(new KeyParameter(k1), Iv));
            }
            else
            {
                Cipher.Init(true, new KeyParameter(k1));
            }

            byte[] c = Cipher.DoFinal(@in, inOff, inLen);


            // Apply the MAC.
            byte[] T = new byte[Mac.GetMacSize()];

            Mac.Init(new KeyParameter(k2));
            Mac.BlockUpdate(c, 0, c.Length);
            Mac.DoFinal(T, 0);

            int cipherBlockSize      = Cipher.GetBlockSize();
            int messageToEncryptSize = inLen - inOff;

            int messageToEncryptPadSize = (messageToEncryptSize % cipherBlockSize) == 0
                ? 0
                : cipherBlockSize -
                                          (messageToEncryptSize % cipherBlockSize);


            // Output the quadruple (SECURE_HEAD_DETAILS,V,T,C).
            // SECURE_HEAD_DETAILS :=
            // [0] := Convert Byte(Length(V)) to a ByteArray,
            // [1] := Convert Byte(Length(T)) to a ByteArray,
            // [2] and [3] := Convert UInt16(MessageToEncryptSize) to a ByteArray,
            // [4] and [5] := Convert UInt16(MessageToEncryptSize + MessageToEncryptPadSize) to a ByteArray,
            // V := Ephemeral Public Key
            // T := Authentication Message (MAC)
            // C := Encrypted Payload

            byte[] output = new byte[SecureHeadSize + V.Length + T.Length + c.Length];


            fixed(byte *ptrByteOutput = output)
            {
                ushort *ptrUShortOutput = (ushort *)ptrByteOutput;

                *ptrByteOutput = (byte)(V.Length);
                *(ptrByteOutput + 1)   = (byte)(T.Length);
                *(ptrUShortOutput + 1) = (ushort)(messageToEncryptSize);
                *(ptrUShortOutput + 2) = (ushort)(messageToEncryptSize + messageToEncryptPadSize);
            }

            Array.Copy(V, 0, output, SecureHeadSize, V.Length);
            Array.Copy(T, 0, output, SecureHeadSize + V.Length, T.Length);
            Array.Copy(c, 0, output, SecureHeadSize + V.Length + T.Length, c.Length);
            return(output);
        }